{
  "openapi": "3.0.4",
  "info": {
    "title": "Donorfy API",
    "description": "RESTful API for the Donorfy CRM platform.\r\n\r\n<div>\r\n<div id=\"UsingAPICollapseAfter\"></div>\r\n<div><strong>Authentication</strong> — every request must be authenticated with one of:</div>\r\n<ul>\r\n<li><em>System (Basic) auth</em>, for system-to-system integrations: <code>Authorization: Basic base64(&lt;PermissionName&gt;:&lt;AccessKey&gt;)</code> together with <code>X-API-Key: &lt;tenantCode&gt;</code>.</li>\r\n<li><em>Access Identity (Bearer) auth</em>, for interactive users: <code>Authorization: Bearer &lt;access_token&gt;</code> together with <code>X-InstanceId: &lt;ApplicationSubscriptionId&gt;</code>.</li>\r\n</ul>\r\n<div><strong>Paging</strong> — collection endpoints are paged. Use <code>usePaging</code>, <code>pageNumber</code> and <code>pageSize</code>; the total count and navigation links are returned in the response headers.</div>\r\n<div><strong>Sorting and includes</strong> — collection endpoints accept <code>sortBy</code>/<code>sortDirection</code>, and detail endpoints accept <code>include</code> to expand related resources.</div>\r\n</div>",
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://preprodapi.donorfy.npe.accessacloud.com/"
    }
  ],
  "paths": {
    "/v1/address-lookup/find": {
      "get": {
        "tags": [
          "Hidden"
        ],
        "summary": "Searches for the addresses matching the text typed so far.",
        "operationId": "GetAddressCandidates",
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "description": "The text typed so far.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "container",
            "in": "query",
            "description": "Identifier of the candidate being drilled into, taken from a candidate returned by an\r\nearlier search that is not an address.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The candidates matching the text.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AddressLookup.AddressCandidateApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The text is missing, or Loqate did not accept the text or the container.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressLookup.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Address lookup is not set up for the instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "The instance's Loqate allowance has been used up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The addresses could not be searched for."
          }
        }
      }
    },
    "/v1/address-lookup/retrieve": {
      "get": {
        "tags": [
          "Hidden"
        ],
        "summary": "Retrieves the full address behind an address candidate.",
        "operationId": "GetAddress",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "description": "Identifier of the candidate, as returned by the search.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The retrieved address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressLookup.AddressApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The identifier is missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressLookup.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to look addresses up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Address lookup is not set up for the instance, or there is no address with that identifier,\r\nwhich includes an identifier Loqate does not recognise.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "The instance's Loqate allowance has been used up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The address could not be retrieved."
          }
        }
      }
    },
    "/v1/address-lookup/settings": {
      "get": {
        "tags": [
          "Hidden"
        ],
        "summary": "Gets how address lookup is set up for the instance.",
        "description": "A client calls this before offering an address search: the search and retrieve endpoints\r\nanswer with a 404 for an instance that holds no Loqate key, and `isEnabled` tells the\r\nclient that up front. The countries the instance searches are applied server side by the\r\nsearch endpoint, and the instance's Loqate key is never returned.",
        "operationId": "GetAddressLookupSettings",
        "responses": {
          "200": {
            "description": "The address lookup settings of the instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressLookup.AddressLookupSettingsApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The settings could not be read."
          }
        }
      }
    },
    "/v1/campaigns": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Lists your campaigns.",
        "description": "The results are paged, filtered and sorted with the query string parameters below. Paging\r\nis on by default and returns 100 campaigns per page; the page details are returned in the\r\n`X-Pagination-PageSize`, `X-Pagination-PageNumber`,\r\n`X-Pagination-HasNextPage`, `X-Pagination-TotalCount` and\r\n`X-Pagination-PageCount` response headers, and the links to the other pages in the\r\n`X-Pagination-Links-*` headers. Campaigns are ordered by description unless a sort is\r\nsupplied.\r\n<br /><br />\r\nA caller holding only the `AccessOwnCampaigns` role is restricted to the campaigns\r\nthey own, whichever filters are supplied.",
        "operationId": "GetCampaigns",
        "parameters": [
          {
            "name": "Search",
            "in": "query",
            "description": "Matches campaigns whose description or campaign type contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Matches the campaign with this identifier.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "CampaignNumber",
            "in": "query",
            "description": "Matches the campaign with this campaign number.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int64"
            }
          },
          {
            "name": "Description",
            "in": "query",
            "description": "Matches campaigns whose description contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignType",
            "in": "query",
            "description": "Matches campaigns whose campaign type is exactly this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsActive",
            "in": "query",
            "description": "Matches active (`true`) or inactive (`false`) campaigns.\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Year",
            "in": "query",
            "description": "Matches campaigns recorded against exactly this year.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "IsEvent",
            "in": "query",
            "description": "Matches campaigns that are events (`true`) or ordinary campaigns (`false`).\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Notes",
            "in": "query",
            "description": "Matches campaigns whose notes contain this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "DefaultProduct",
            "in": "query",
            "description": "Matches campaigns whose default product contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "DefaultFund",
            "in": "query",
            "description": "Matches campaigns whose default fund contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ChannelId",
            "in": "query",
            "description": "Matches campaigns run through the channel with this identifier.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Channel",
            "in": "query",
            "description": "Matches campaigns whose channel contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ConstituentsBudgetFrom",
            "in": "query",
            "description": "Matches campaigns budgeted to recruit at least this many constituents.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "ConstituentsBudgetTo",
            "in": "query",
            "description": "Matches campaigns budgeted to recruit at most this many constituents.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "TransactionsBudgetFrom",
            "in": "query",
            "description": "Matches campaigns budgeted to raise at least this much income.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "TransactionsBudgetTo",
            "in": "query",
            "description": "Matches campaigns budgeted to raise at most this much income.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "ExpensesTotalFrom",
            "in": "query",
            "description": "Matches campaigns with at least this much expense recorded against them.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "ExpensesTotalTo",
            "in": "query",
            "description": "Matches campaigns with at most this much expense recorded against them.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "AudienceSizeFrom",
            "in": "query",
            "description": "Matches campaigns aimed at at least this many people.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "AudienceSizeTo",
            "in": "query",
            "description": "Matches campaigns aimed at at most this many people.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "ContactConstituentId",
            "in": "query",
            "description": "Matches campaigns whose contact is the constituent with this identifier.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "CampaignMembersListId",
            "in": "query",
            "description": "Matches campaigns whose members are held in the list definition with this identifier.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "OwnerId",
            "in": "query",
            "description": "Matches campaigns owned by the user with this identifier.\r\n<ul><li>Ignored for users who may only access the campaigns they own; their requests are always\r\nscoped to themselves.</li></ul>",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Owner",
            "in": "query",
            "description": "Matches campaigns whose owner full name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "DateAddedFrom",
            "in": "query",
            "description": "Matches campaigns created on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateAddedTo",
            "in": "query",
            "description": "Matches campaigns created on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedFrom",
            "in": "query",
            "description": "Matches campaigns last changed on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedTo",
            "in": "query",
            "description": "Matches campaigns last changed on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "description",
                "year",
                "dateAdded",
                "campaignNumber"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of campaigns matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Campaign.CampaignListApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort or paging value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read campaigns.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The campaigns could not be retrieved."
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Retrieves a single campaign.",
        "description": "A caller holding only the `AccessOwnCampaigns` role can retrieve the campaigns they\r\nown; a campaign owned by somebody else is reported as not found rather than as forbidden.",
        "operationId": "GetCampaignById",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "description": "Identifier of the campaign to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested campaign.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Campaign.CampaignDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The identifier is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read campaigns.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No campaign with that identifier exists, or it is not owned by the caller.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The campaign could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}/tags": {
      "get": {
        "tags": [
          "Constituents - Tags"
        ],
        "summary": "Lists the tags allocated to a constituent.",
        "description": "Both the tags still allocated to the constituent and those that have been removed from it\r\nare returned; filter with `isActive=true` for the tags it currently carries. Only tags\r\nof categories that are active and can be applied to a constituent are returned.\r\n<br /><br />\r\nThe results are paged, filtered and sorted with the query string parameters below. Paging is\r\non by default and returns 100 tags per page; the page details are returned in the\r\n`X-Pagination-*` response headers. Tags are ordered by name unless a sort is supplied.",
        "operationId": "GetConstituentTags",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent whose tags are returned.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "TagCategory",
            "in": "query",
            "description": "Matches tags in this category.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "TagName",
            "in": "query",
            "description": "Matches tags with this name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsActive",
            "in": "query",
            "description": "Matches tags that are still allocated to the constituent when `true`, and tags that\r\nhave been removed from it when `false`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsPinned",
            "in": "query",
            "description": "Matches tags whose category is configured to be pinned when `true`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "tagName",
                "tagCategory",
                "isActive",
                "isPinned"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of tags allocated to the constituent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Constituent.TagApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort or paging value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The tags could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}/tags/{tagId}": {
      "get": {
        "tags": [
          "Constituents - Tags"
        ],
        "summary": "Retrieves a single tag allocated to a constituent.",
        "description": "The identifier is that of the tag allocated to the constituent, as returned by the list\r\nendpoint. A tag of a category the caller is not permitted to see, or of a category that is\r\nnot active or cannot be applied to a constituent, is reported as not found.",
        "operationId": "GetConstituentTagById",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent the tag is allocated to.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "tagId",
            "in": "path",
            "description": "Identifier of the tag allocated to the constituent.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested tag.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.TagApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "An identifier is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists, or it does not carry that tag.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The tag could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}/contact-details": {
      "get": {
        "tags": [
          "Constituents - Contact Details"
        ],
        "summary": "Lists the contact details of a constituent.",
        "description": "Every set of contact details recorded against the constituent is returned, one per contact\r\ndetails type, and only the values that have been recorded are populated. The results are\r\nnot paged, filtered or sorted.",
        "operationId": "GetConstituentContactDetails",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent whose contact details are returned.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The contact details of the constituent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Constituent.ContactDetailApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The contact details could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}/contact-details/{contactDetailsId}": {
      "get": {
        "tags": [
          "Constituents - Contact Details"
        ],
        "summary": "Retrieves a single set of contact details of a constituent.",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent the contact details belong to.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "contactDetailsId",
            "in": "path",
            "description": "Identifier of the contact details to return.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The contact details.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.ContactDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No contact details with that identifier exist for the constituent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The contact details could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents": {
      "get": {
        "tags": [
          "Constituents"
        ],
        "summary": "Lists your constituents.",
        "description": "The results are paged, filtered and sorted with the query string parameters below. Paging\r\nis on by default and returns 100 constituents per page; the page details are returned in\r\nthe `X-Pagination-PageSize`, `X-Pagination-PageNumber`,\r\n`X-Pagination-HasNextPage`, `X-Pagination-TotalCount` and\r\n`X-Pagination-PageCount` response headers, and the links to the other pages in the\r\n`X-Pagination-Links-*` headers. Constituents are ordered by constituent number unless\r\na sort is supplied.\r\n<br /><br />\r\nThe pinned tags of the constituents are only returned when they are asked for with\r\n`include=pinnedTags`.",
        "operationId": "GetConstituents",
        "parameters": [
          {
            "name": "LastName",
            "in": "query",
            "description": "Matches constituents whose last name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "FirstName",
            "in": "query",
            "description": "Matches constituents whose first name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "OrganisationName",
            "in": "query",
            "description": "Matches constituents whose organisation name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ConstituentNumber",
            "in": "query",
            "description": "Matches the constituent with this constituent number.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int64"
            }
          },
          {
            "name": "IsActive",
            "in": "query",
            "description": "Matches active (`true`) or archived (`false`) constituents.\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Prefix",
            "in": "query",
            "description": "Matches constituents whose name prefix contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "AlsoKnownAs",
            "in": "query",
            "description": "Matches constituents whose alternative name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "DateOfBirthFrom",
            "in": "query",
            "description": "Matches constituents born on or after this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "DateOfBirthTo",
            "in": "query",
            "description": "Matches constituents born on or before this date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "NationalIDNumber",
            "in": "query",
            "description": "Matches constituents with exactly this national identification number.\r\n<ul><li>Ignored for an Access Identity user without the `AccessNationalIdentity` role.</li></ul>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsGroup",
            "in": "query",
            "description": "Matches group constituents such as organisations (`true`) or individuals (`false`).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "ArchiveDateFrom",
            "in": "query",
            "description": "Matches constituents archived on or after this date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "ArchiveDateTo",
            "in": "query",
            "description": "Matches constituents archived on or before this date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "NoGiftAid",
            "in": "query",
            "description": "Matches constituents that are excluded from Gift Aid claims (`true`) or not (`false`).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "DateAddedFrom",
            "in": "query",
            "description": "Matches constituents created on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateAddedTo",
            "in": "query",
            "description": "Matches constituents created on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedFrom",
            "in": "query",
            "description": "Matches constituents last changed on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedTo",
            "in": "query",
            "description": "Matches constituents last changed on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "ExternalKey",
            "in": "query",
            "description": "Matches constituents with exactly this external key.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Search",
            "in": "query",
            "description": "Matches constituents with a full text search across their searchable details.\r\n<ul><li>Words are matched as prefixes, so `smi` also matches `Smith`.</li><li>The full text operators `\" &amp; | ~ ! ( ) { } [ ] ^ *` are removed from the value before searching.</li></ul>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ConstituentType",
            "in": "query",
            "description": "Matches constituents whose type contains this value, as described in the `Constituent Types` lookup.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Gender",
            "in": "query",
            "description": "Matches constituents whose gender contains this value, as described in the `Genders` lookup.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ArchiveReason",
            "in": "query",
            "description": "Matches constituents whose archive reason contains this value, as described in the `Archive Reasons` lookup.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "RecruitmentCampaign",
            "in": "query",
            "description": "Matches constituents whose recruitment campaign name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "JobTitle",
            "in": "query",
            "description": "Matches constituents whose main contact details job title contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Department",
            "in": "query",
            "description": "Matches constituents whose main contact details department contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Salutation",
            "in": "query",
            "description": "Matches constituents whose main contact details salutation contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "LabelName",
            "in": "query",
            "description": "Matches constituents whose main contact details label name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "HouseBuildingNumber",
            "in": "query",
            "description": "Matches constituents whose main address house name or number contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "AddressLine1",
            "in": "query",
            "description": "Matches constituents whose main address first line contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "AddressLine2",
            "in": "query",
            "description": "Matches constituents whose main address second line contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Town",
            "in": "query",
            "description": "Matches constituents whose main address town contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "County",
            "in": "query",
            "description": "Matches constituents whose main address county contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PostalCode",
            "in": "query",
            "description": "Matches constituents whose main address postal code contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Country",
            "in": "query",
            "description": "Matches constituents whose main address country contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Phone1",
            "in": "query",
            "description": "Matches constituents whose main contact details first phone number contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Phone2",
            "in": "query",
            "description": "Matches constituents whose main contact details second phone number contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "MobilePhone",
            "in": "query",
            "description": "Matches constituents whose main contact details mobile phone number contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Email1Address",
            "in": "query",
            "description": "Matches constituents whose main contact details first email address contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Email1Format",
            "in": "query",
            "description": "Matches constituents whose first email address is sent in this format.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Email2Address",
            "in": "query",
            "description": "Matches constituents whose main contact details second email address contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Email2Format",
            "in": "query",
            "description": "Matches constituents whose second email address is sent in this format.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "LinkedToConstituentId",
            "in": "query",
            "description": "Matches constituents whose main address is shared with this constituent.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "Include",
            "in": "query",
            "description": "One or more related resources to expand in the response, separated by commas.",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "enum": [
                  "pinnedTags"
                ],
                "type": "string"
              }
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "constituentNumber",
                "lastName",
                "firstName",
                "organisationName",
                "dateOfBirth",
                "nationalIDNumber",
                "archiveDate",
                "dateAdded",
                "dateChanged",
                "constituentType",
                "gender",
                "archiveReason",
                "recruitmentCampaign",
                "jobTitle",
                "department",
                "salutation",
                "labelName",
                "houseBuildingNumber",
                "addressLine1",
                "addressLine2",
                "town",
                "county",
                "postalCode",
                "country",
                "phone1",
                "phone2",
                "mobilePhone",
                "email1Address",
                "email1Format",
                "email2Address",
                "email2Format",
                "linkedToConstituentId"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of constituents matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Constituent.ConstituentApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort, paging or `include` value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The constituents could not be retrieved."
          }
        }
      },
      "post": {
        "tags": [
          "Constituents"
        ],
        "summary": "Creates a constituent.",
        "description": "The constituent type decides which details are accepted: a group type such as\r\n`Organisation` is described by `organisationName` and rejects the person\r\nproperties, which belong in the nested `mainContact` object instead. Supplying\r\n`mainContact` creates an individual as the main contact of the group, returned as\r\n`mainContact`; a group without it creates the group alone. The\r\nconstituent type, gender and recruitment campaign must already exist, and each is given as\r\neither its identifier or its name.\r\n<br /><br />`channelPreferences` records the keep in touch preferences of the constituent, given\r\nper channel as `preferenceAllowed` for `email`, `phone`, `mail` and\r\n`sms`. A channel left out, like the whole object when it is omitted, is recorded\r\nunconfirmed and reads back with a `preferenceAllowed` of `null`.\r\n<br /><br />\r\nThe contact detail properties such as `addressLine1`, `phone1` and\r\n`email1Address` are stored on the main contact details of the constituent. The main\r\ncontact holds the ones supplied inside `mainContact`, along with its own recruitment\r\ncampaign, `noGiftAid`, `externalKey` and channel preferences: nothing is copied\r\nto it from the group. The properties left out keep their\r\ndefaults. Tags are not accepted.\r\nThe location of the created constituent is returned in the `Location` response header.\r\nRequires a user in the `Admin` or `Standard` role.\r\n<br /><br />`nationalIDNumber` is stored and echoed back as it is given: the\r\n`AccessNationalIdentity` role is only needed to read a national identification number\r\nback from the constituent endpoints, or to change one through `PATCH`.",
        "operationId": "CreateConstituent",
        "requestBody": {
          "description": "Details of the constituent to create.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Constituent.CreateConstituentApiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The constituent that was created, described the same way `GET /v1/constituents/{constituentId}?include=channelPreferences` describes it, with its location in the `Location` header. The main contact created alongside a group is returned on top of what a read returns, as `mainContact`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.CreatedConstituentApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid, for example an unknown constituent type or a value that is too long.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The constituent could not be created."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}": {
      "get": {
        "tags": [
          "Constituents"
        ],
        "summary": "Retrieves a single constituent.",
        "description": "The contact details, tracking codes, tags, channel preferences and giving summary of the\r\nconstituent are only returned when they are asked for with `include`.\r\n\r\nA requested `givingSummary` is omitted, rather than rejected, for a user who is not\r\npermitted to see financial information.",
        "operationId": "GetConstituentById",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Include",
            "in": "query",
            "description": "One or more related resources to expand in the response, separated by commas.",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "enum": [
                  "contactDetails",
                  "trackingCodes",
                  "tags",
                  "channelPreferences",
                  "givingSummary"
                ],
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested constituent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.ConstituentDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The identifier or an `include` value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The constituent could not be retrieved."
          }
        }
      },
      "delete": {
        "tags": [
          "Constituents"
        ],
        "summary": "Permanently deletes a constituent.",
        "description": "The constituent and its financial summary are removed from the database; this cannot be\r\nundone. Archive the constituent instead when a record of it must be kept. Requires a user\r\nin the `Admin` or `Standard` role.",
        "operationId": "DeleteConstituent",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent to delete.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The constituent was deleted."
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The constituent could not be deleted."
          }
        }
      },
      "patch": {
        "tags": [
          "Constituents"
        ],
        "summary": "Changes part of a constituent with a JSON Patch document.",
        "description": "The request body is a JSON Patch document sent as `application/json-patch+json`, for\r\nexample `[{ \"op\": \"replace\", \"path\": \"/lastName\", \"value\": \"Smith\" }]`.\r\n<br /><br />\r\nThe paths that can be changed are `/organisationName`, `/title`,\r\n`/firstName`, `/middleName`, `/lastName`, `/prefix`, `/suffix`,\r\n`/formerly`, `/alsoKnownAs`, `/dateOfBirth`, `/nationalIDNumber`,\r\n`/allowNameSwap`, `/noGiftAid`, `/externalKey`,\r\n`/recruitmentCampaign`, `/constituentType` and `/gender`; any other path is\r\nrejected. The values are validated in the\r\nsame way as when creating a constituent: person names cannot be set on a group,\r\n`organisationName` cannot be set on an individual, and the constituent type, gender\r\nand recruitment campaign must exist. Requires a user in the `Admin` or\r\n`Standard` role.",
        "operationId": "PatchConstituent",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent to change.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "description": "JSON Patch operations to apply to the constituent.",
          "content": {
            "application/json-patch+json": {
              "schema": {
                "$ref": "#/components/schemas/JsonPatchDocumentOfPatchConstituentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "The constituent was changed."
          },
          "400": {
            "description": "The patch document could not be applied, or the resulting constituent is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role, or is an Access Identity user that changed `nationalIDNumber` without the `AccessNationalIdentity` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The constituent was changed by another request; retry the patch.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The constituent could not be changed."
          }
        }
      }
    },
    "/v1/constituents/duplicate-check": {
      "post": {
        "tags": [
          "Constituents"
        ],
        "summary": "Checks whether the supplied details match existing constituents.",
        "description": "Intended to be called before creating a constituent. At least one detail must be supplied.\r\nEach duplicate rule that matches contributes a confidence score, and only the constituents\r\nwhose best rule scores above the configured duplicate reporting threshold are returned,\r\nordered by that score. Duplicate checking must be enabled, otherwise the\r\nrequest is rejected. Nothing is created or changed by this endpoint.",
        "operationId": "CheckConstituentsForDuplicates",
        "requestBody": {
          "description": "Details of the person to look for duplicates of.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Constituent.DuplicateCheckApiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The possible duplicates, ordered by score. An empty list means no duplicates were found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Constituent.DuplicateCheckApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "No details were supplied, or duplicate checking is not enabled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The duplicate check could not be completed."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}/channel-preferences": {
      "get": {
        "tags": [
          "Constituents - Channel Preferences"
        ],
        "summary": "Lists the channel preferences of a constituent.",
        "description": "Every channel preference recorded against the constituent is returned, ordered by channel\r\nname. The results are not paged, filtered or sorted.",
        "operationId": "GetConstituentChannelPreferences",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent whose channel preferences are returned.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The channel preferences of the constituent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Constituent.ChannelPreferenceApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No constituent with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The channel preferences could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents/{constituentId}/channel-preferences/{channelPreferenceId}": {
      "get": {
        "tags": [
          "Constituents - Channel Preferences"
        ],
        "summary": "Retrieves a single channel preference of a constituent.",
        "parameters": [
          {
            "name": "constituentId",
            "in": "path",
            "description": "Identifier of the constituent the channel preference belongs to.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "channelPreferenceId",
            "in": "path",
            "description": "Identifier of the channel preference to return.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The channel preference.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.ChannelPreferenceApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read constituents.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No channel preference with that identifier exists for the constituent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The channel preference could not be retrieved."
          }
        }
      }
    },
    "/v1/constituents/activities": {
      "post": {
        "tags": [
          "Activities"
        ],
        "summary": "Records an activity against one of your constituents.",
        "description": "The constituent must already exist: it is never created or matched from the request. The\r\nactivity type is given by its ID or its description, and decides which of the\r\nuser-defined extra fields (`code1` to `code10`, `yesNo1` to\r\n`yesNo10`, `number1` to `number10` and `date1` to `date10`) may\r\nbe given a value: only those it labels.\r\n<br /><br />\r\nThe UTM tracking codes are trimmed and a blank one is treated as not supplied; they are\r\nonly recorded when at least one of them is supplied. A confidential activity needs the\r\n`AccessConfidentialActivities` permission. No task is created for the activity.\r\nThe created activity is returned with every value known once it is recorded, and its\r\nlocation in the `Location` response header.\r\nRequires a user in the `Admin` or `Standard` role.",
        "operationId": "CreateActivity",
        "requestBody": {
          "description": "Details of the activity to record.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Constituent.CreateActivityApiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The activity that was created, with its location in the `Location` header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Constituent.ActivityApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid, for example an unknown constituent or activity type, or a value in an extra field the activity type does not label.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role, or may not record a confidential activity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The activity could not be created."
          }
        }
      }
    },
    "/v1/constituents/activities/{activityId}": {
      "get": {
        "tags": [
          "Activities"
        ],
        "summary": "Retrieves one of your activities. Not implemented yet.",
        "operationId": "GetActivityById",
        "parameters": [
          {
            "name": "activityId",
            "in": "path",
            "description": "The ID of the activity.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "501": {
            "description": "Retrieving an activity is not implemented yet."
          }
        }
      }
    },
    "/v1/instances": {
      "get": {
        "tags": [
          "Hidden"
        ],
        "summary": "Lists the Donorfy instances the authenticated user can work in.",
        "description": "The instances are those of the organisation of the access token that belong to the user the\r\n`email` claim of the token names, and the permissions the `source` needs are\r\nevaluated in each of them. The response is not paged, filtered or sorted.\r\n<br /><br />\r\nThis endpoint serves the selection of an instance by a Donorfy client, so it is deliberately\r\nkept out of the public OpenAPI document.",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "description": "Short name of the calling source, for example `donorfy-constituent-find`, naming the\r\naction the instances are needed for.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter",
            "in": "query",
            "description": "Whether to return only instances the user may perform the action in. By default every\r\ninstance is returned annotated with `hasAccess`.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The instances answered for the source.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InstancesApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The access token is missing the organisation or the email of the user, or the request is\r\nmissing the source.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "The source is not known.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The instances could not be read."
          }
        }
      }
    },
    "/v1/lists/types": {
      "get": {
        "tags": [
          "Lists - Types"
        ],
        "summary": "Lists the list types a list definition can be created for.",
        "description": "Every supported list type is returned; the results are not paged, filtered or sorted. The\r\ncolumns and filters of a list type are returned by\r\n`GET v1/lists/types/{listTypeName}`.",
        "operationId": "GetListTypes",
        "responses": {
          "200": {
            "description": "The supported list types.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Lists.ListTypeApiResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list types could not be retrieved."
          }
        }
      }
    },
    "/v1/lists/types/{listTypeName}": {
      "get": {
        "tags": [
          "Lists - Types"
        ],
        "summary": "Retrieves a single list type, optionally with the columns and filters it offers.",
        "description": "Only the name of the list type is returned unless the columns or the filters are asked for\r\nwith `include=availableColumns`, `include=availableFilters` or both. The name is\r\nmatched without regard to case.",
        "operationId": "GetListTypeByName",
        "parameters": [
          {
            "name": "listTypeName",
            "in": "path",
            "description": "Name of the list type to retrieve, as returned by `GET v1/lists/types`.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Include",
            "in": "query",
            "description": "One or more related resources to expand in the response, separated by commas.",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "enum": [
                  "availableColumns",
                  "availableFilters"
                ],
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested list type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListTypeDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "An `include` value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No list type with that name is supported.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list type could not be retrieved."
          }
        }
      }
    },
    "/v1/lists/{listDefinitionId}/runs": {
      "post": {
        "tags": [
          "Lists - Runs"
        ],
        "summary": "Starts a run of a list definition.",
        "description": "The run is accepted and then generated in the background, so the response only carries the\r\nidentifier of the run; its location is returned in the `Location` response header and\r\nits progress is followed with `GET v1/lists/{listDefinitionId}/runs/{runId}`.\r\n<br /><br />\r\nWhen the list is already being generated the run in progress is returned instead of starting\r\nanother one, and the reason is given in `message`. Generating too many lists at once is\r\nrate limited.",
        "operationId": "CreateListRun",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition to run.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "The run that was accepted for generation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.GenerateListRunApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No list definition with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too many runs are being generated at the moment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The run could not be started."
          },
          "502": {
            "description": "The service that generates the run could not be reached."
          }
        }
      },
      "get": {
        "tags": [
          "Lists - Runs"
        ],
        "summary": "Lists the runs of a list definition, most useful for showing when the list was last\r\ngenerated.",
        "description": "The results are always paged and return 50 runs per page unless a page size is supplied; the\r\npage details are returned in the `X-Pagination-PageSize`,\r\n`X-Pagination-PageNumber`, `X-Pagination-HasNextPage`,\r\n`X-Pagination-TotalCount` and `X-Pagination-PageCount` response headers, and the\r\nlinks to the other pages in the `X-Pagination-Links-*` headers.",
        "operationId": "GetListRunHistory",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition whose runs are returned.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of runs of the list definition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListRunHistoryApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "A paging value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The runs could not be retrieved."
          }
        }
      }
    },
    "/v1/lists/{listDefinitionId}/runs/{runId}": {
      "get": {
        "tags": [
          "Lists - Runs"
        ],
        "summary": "Retrieves the status of a single run of a list definition.",
        "description": "The rows of the run are read with\r\n`GET v1/lists/{listDefinitionId}/runs/{runId}/results` once the status is\r\n`Complete`.",
        "operationId": "GetListRun",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition the run belongs to.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "description": "Identifier of the run to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListRunApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No run with that identifier exists for the list definition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The run could not be retrieved."
          }
        }
      }
    },
    "/v1/lists/{listDefinitionId}/runs/{runId}/results": {
      "get": {
        "tags": [
          "Lists - Runs"
        ],
        "summary": "Retrieves the rows a completed run of a list definition produced.",
        "description": "The rows are only available once the run has finished successfully; a run that is still being\r\ngenerated, was cancelled or failed has no results. The results are paged and the page details\r\nare returned in the `X-Pagination-*` response headers; a page may hold at most 10,000\r\nrows.\r\n<br /><br />\r\nThe columns of the rows are returned in `availableColumns`, and `sortBy` has to be\r\none of them.",
        "operationId": "GetListRunResults",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition the run belongs to.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "description": "Identifier of the run whose rows are returned.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "Column of the run the rows are sorted by; one of the values in `availableColumns`. The rows are returned in the order the run produced them when it is not supplied.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Direction the rows are sorted in, either `ascending` or `descending`. Defaults to `ascending`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of rows of the run, together with the columns they hold.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListRunResultsApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid, for example the page size is out of range, `sortBy` is not a column of the run, `sortDirection` is not recognised or the run has not completed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No run with that identifier exists for the list definition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The rows could not be retrieved."
          }
        }
      }
    },
    "/v1/lists/{listDefinitionId}/runs/{runId}/cancellation": {
      "post": {
        "tags": [
          "Lists - Runs"
        ],
        "summary": "Cancels a run of a list definition that has not finished yet.",
        "description": "Only a run that is waiting to start, preparing or processing can be cancelled; a run that has\r\nalready completed, failed or been cancelled is rejected. The status the run ended up in is\r\nreturned.",
        "operationId": "CancelListRun",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition the run belongs to.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "description": "Identifier of the run to cancel.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The run as it is after the cancellation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.CancelListRunApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The run cannot be cancelled, for example because it has already finished.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No run with that identifier exists for the list definition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The run could not be cancelled."
          }
        }
      }
    },
    "/v1/lists": {
      "get": {
        "tags": [
          "Lists"
        ],
        "summary": "Lists your list definitions.",
        "description": "The results are paged, filtered and sorted with the query string parameters below. Paging\r\nis on by default and returns 100 list definitions per page; the page details are returned in\r\nthe `X-Pagination-PageSize`, `X-Pagination-PageNumber`,\r\n`X-Pagination-HasNextPage`, `X-Pagination-TotalCount` and\r\n`X-Pagination-PageCount` response headers, and the links to the other pages in the\r\n`X-Pagination-Links-*` headers. List definitions are ordered by list type and then by\r\ndescription unless a sort is supplied.\r\n<br /><br />\r\nThe filters and output fields of a list definition are only returned when a single list\r\ndefinition is retrieved.",
        "operationId": "GetListDefinitions",
        "parameters": [
          {
            "name": "ListType",
            "in": "query",
            "description": "Matches the list definitions of exactly this list type.\r\n<ul><li>Must be one of the list types returned by `GET v1/lists/types`.</li></ul>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "listType",
                "listDescription",
                "rowCount",
                "rowCountDate"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of list definitions matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Lists.ListDefinitionApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort or paging value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list definitions could not be retrieved."
          }
        }
      },
      "post": {
        "tags": [
          "Lists"
        ],
        "summary": "Creates a list definition.",
        "description": "Only the list type and the description are given when the list is created; the new list has\r\nno filters and is not shown in the menu, does not include archived constituents and does not\r\ninclude confidential activities. The filters and the other options are set afterwards with\r\n`PUT v1/lists/{listDefinitionId}`.\r\n<br /><br />\r\nThe location of the new list definition is returned in the `Location` response header.",
        "operationId": "CreateListDefinition",
        "requestBody": {
          "description": "The list type and description of the list definition to create.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Lists.CreateListDefinitionApiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The list definition that was created, described the same way `GET /v1/lists/{listDefinitionId}` describes it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListDefinitionDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid, for example the list type is unknown or the description is missing or too long.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list definition could not be created."
          }
        }
      }
    },
    "/v1/lists/{listDefinitionId}": {
      "get": {
        "tags": [
          "Lists"
        ],
        "summary": "Retrieves a single list definition, together with its filters and output fields.",
        "description": "The filter definition of the list is read from the stored list XML, so it holds every filter\r\nrow of the list, including the system rows Donorfy maintains itself.",
        "operationId": "GetListDefinitionById",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested list definition.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListDefinitionDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No list definition with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list definition could not be retrieved."
          }
        }
      },
      "put": {
        "tags": [
          "Lists"
        ],
        "summary": "Updates a list definition and the filters it selects rows with.",
        "description": "The whole list definition is replaced: every property of the request is applied and the\r\nfilters supplied become the filters of the list, so the filters that are to be kept must be\r\nsent again. The updated list definition is returned.\r\n<br /><br />\r\nEach filter is checked before it is stored: the field, display name, operator, joins and\r\ndata type are required, the operator must be one that applies to the data type of the field,\r\nand the brackets must balance across the filters. Filter rows flagged with\r\n`system: true` are stored as they are sent and are not validated.\r\n<br /><br />\r\nA list that is locked by another user cannot be updated.",
        "operationId": "UpdateListDefinition",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition to update.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "description": "The properties and filters to store against the list definition.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Lists.UpdateListDefinitionApiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The list definition as it is after the update.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lists.ListDefinitionDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid, for example a filter is incomplete, an operator does not apply to the data type of the field or the brackets do not balance. Every validation error of the request is returned together.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No list definition with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The list definition is locked and cannot be updated at the moment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list definition could not be updated."
          }
        }
      },
      "delete": {
        "tags": [
          "Lists"
        ],
        "summary": "Deletes a list definition.",
        "description": "A list definition can only be deleted by the user who added it or by an administrator, and\r\nnot while it is locked. Nothing is returned when the list definition has been deleted.",
        "operationId": "DeleteListDefinition",
        "parameters": [
          {
            "name": "listDefinitionId",
            "in": "path",
            "description": "Identifier of the list definition to delete.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The list definition was deleted."
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessDataLists` role, or is neither the user who added the list definition nor an administrator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No list definition with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "The list definition is locked and cannot be deleted at the moment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The list definition could not be deleted."
          }
        }
      }
    },
    "/v1/lookup-types": {
      "get": {
        "tags": [
          "Lookup Types"
        ],
        "summary": "Lists your lookup types.",
        "description": "The results are paged, filtered and sorted with the query string parameters below. Paging\r\nis on by default and returns 100 lookup types per page; the page details are returned in\r\nthe `X-Pagination-PageSize`, `X-Pagination-PageNumber`,\r\n`X-Pagination-HasNextPage`, `X-Pagination-TotalCount` and\r\n`X-Pagination-PageCount` response headers, and the links to the other pages in the\r\n`X-Pagination-Links-*` headers. Lookup types are ordered by name unless a sort is\r\nsupplied.",
        "operationId": "GetLookupTypes",
        "parameters": [
          {
            "name": "IsActive",
            "in": "query",
            "description": "Matches active (`true`) or inactive (`false`) lookup types.\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsSystem",
            "in": "query",
            "description": "Matches lookup types that are (`true`) or are not (`false`) system lookup types.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "LookupTypeName",
            "in": "query",
            "description": "Matches lookup types whose name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "LookupTypeDescription",
            "in": "query",
            "description": "Matches lookup types whose description contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Language",
            "in": "query",
            "description": "Matches lookup types whose language code is exactly this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "StoreDescription",
            "in": "query",
            "description": "Matches lookup types whose `storeDescription` flag is this value.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "AllowBlank",
            "in": "query",
            "description": "Matches lookup types whose `allowBlank` flag is this value.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "DateAddedFrom",
            "in": "query",
            "description": "Matches lookup types created on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateAddedTo",
            "in": "query",
            "description": "Matches lookup types created on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedFrom",
            "in": "query",
            "description": "Matches lookup types last changed on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedTo",
            "in": "query",
            "description": "Matches lookup types last changed on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Search",
            "in": "query",
            "description": "Matches lookup types whose name or description contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "lookupTypeName",
                "dateAdded",
                "dateChanged"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of lookup types matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Lookups.LookupTypeApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort or paging value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookups.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read lookup types.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The lookup types could not be retrieved."
          }
        }
      }
    },
    "/v1/lookup-types/{lookupTypeId}": {
      "get": {
        "tags": [
          "Lookup Types"
        ],
        "summary": "Retrieves a single lookup type.",
        "description": "The lookups belonging to the lookup type are retrieved separately, with\r\n`GET v1/lookups?lookupTypeId={lookupTypeId}`.",
        "operationId": "GetLookupTypeById",
        "parameters": [
          {
            "name": "lookupTypeId",
            "in": "path",
            "description": "Identifier of the lookup type to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested lookup type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookups.LookupTypeApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read lookup types.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No lookup type with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The lookup type could not be retrieved."
          }
        }
      }
    },
    "/v1/lookups": {
      "get": {
        "tags": [
          "Lookups"
        ],
        "summary": "Lists your lookups.",
        "description": "The results are paged, filtered and sorted with the query string parameters below. Paging\r\nis on by default and returns 100 lookups per page; the page details are returned in the\r\n`X-Pagination-PageSize`, `X-Pagination-PageNumber`,\r\n`X-Pagination-HasNextPage`, `X-Pagination-TotalCount` and\r\n`X-Pagination-PageCount` response headers, and the links to the other pages in the\r\n`X-Pagination-Links-*` headers. Lookups are ordered by description unless a sort is\r\nsupplied.",
        "operationId": "GetLookups",
        "parameters": [
          {
            "name": "IsActive",
            "in": "query",
            "description": "Matches active (`true`) or inactive (`false`) lookups.\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "LookupDescription",
            "in": "query",
            "description": "Matches lookups whose description contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "LookupTypeId",
            "in": "query",
            "description": "Matches the lookups belonging to this lookup type.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "LookupTypeDescription",
            "in": "query",
            "description": "Matches lookups whose lookup type description contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Search",
            "in": "query",
            "description": "Matches lookups whose description or lookup type description contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "lookupDescription",
                "dateAdded",
                "dateChanged"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of lookups matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Lookups.LookupApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort or paging value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookups.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read lookups.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The lookups could not be retrieved."
          }
        }
      }
    },
    "/v1/lookups/{lookupId}": {
      "get": {
        "tags": [
          "Lookups"
        ],
        "summary": "Retrieves a single lookup.",
        "operationId": "GetLookupById",
        "parameters": [
          {
            "name": "lookupId",
            "in": "path",
            "description": "Identifier of the lookup to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested lookup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookups.LookupApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The identifier is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lookups.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not permitted to read lookups.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No lookup with that identifier exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The lookup could not be retrieved."
          }
        }
      }
    },
    "/v1/transactions": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Lists your payments.",
        "description": "Only payments are returned; the allocations splitting a payment across products and funds\r\nare returned inside their payment when they are asked for with `include=allocations`,\r\nwhich requires paging with a page size of 500 or fewer. A payment with no allocations\r\nreturns an empty `allocations` array, and the allocations returned are not filtered by\r\nthe payment's `isActive` or `transactionStatus`.\r\n<br /><br />\r\nThe results are paged, filtered and sorted with the query string parameters below. Paging\r\nis on by default and returns 100 payments per page; the page details are returned in the\r\n`X-Pagination-PageSize`, `X-Pagination-PageNumber`,\r\n`X-Pagination-HasNextPage`, `X-Pagination-TotalCount` and\r\n`X-Pagination-PageCount` response headers, and the links to the other pages in the\r\n`X-Pagination-Links-*` headers. Payments are ordered by the date they were paid, most\r\nrecent first, unless a sort is supplied. Transaction number, highest first, breaks ties in\r\nthe sort, so that a page boundary falls in the same place each time the list is read.\r\n<br /><br />`dateAddedFrom`/`dateAddedTo` and `dateChangedFrom`/`dateChangedTo`\r\nread only the payments added or changed in a window, which is how an integration keeps a\r\ncopy of your payments up to date without reading them all again.\r\n<br /><br />\r\nRequires the `AccessTransactionsRpis` permission.",
        "operationId": "GetTransactions",
        "parameters": [
          {
            "name": "ConstituentId",
            "in": "query",
            "description": "Matches the payments of this constituent.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "TransactionNumber",
            "in": "query",
            "description": "Matches the payment with this transaction number.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int64"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Matches the payments attributed to this campaign.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Campaign",
            "in": "query",
            "description": "Matches payments whose campaign name contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PaymentMethod",
            "in": "query",
            "description": "Matches payments whose payment method contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PaymentMethodId",
            "in": "query",
            "description": "Matches the payments recorded with this payment method.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Currency",
            "in": "query",
            "description": "Matches payments whose currency contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CurrencyId",
            "in": "query",
            "description": "Matches the payments recorded in this currency.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Channel",
            "in": "query",
            "description": "Matches payments whose channel contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ChannelId",
            "in": "query",
            "description": "Matches the payments that came through this channel.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "BankAccount",
            "in": "query",
            "description": "Matches payments whose bank account contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "BankAccountId",
            "in": "query",
            "description": "Matches the payments paid into this bank account.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Acknowledgement",
            "in": "query",
            "description": "Matches payments whose acknowledgement contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "AcknowledgementId",
            "in": "query",
            "description": "Matches the payments acknowledged with this acknowledgement.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "ConstituentNumber",
            "in": "query",
            "description": "Matches the payments of the constituent with this number.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int64"
            }
          },
          {
            "name": "ConnectedConstituentId",
            "in": "query",
            "description": "Matches the payments connected to this constituent.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "FundraisingPageId",
            "in": "query",
            "description": "Matches the payments attributed to this fundraising page.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "RecurringPaymentInstructionId",
            "in": "query",
            "description": "Matches the payments collected by this recurring payment instruction.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Reference",
            "in": "query",
            "description": "Matches payments whose reference contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "PayoutReference",
            "in": "query",
            "description": "Matches payments whose payout reference contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Comments",
            "in": "query",
            "description": "Matches payments whose comments contain this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "EnteredByUser",
            "in": "query",
            "description": "Matches payments whose entering user contains this value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "GiftAidStatus",
            "in": "query",
            "description": "Matches payments with exactly this Gift Aid status.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsRecurringGift",
            "in": "query",
            "description": "Matches payments that are (`true`) or are not (`false`) flagged as a recurring\r\ngift.\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "AmountFrom",
            "in": "query",
            "description": "Matches payments of at least this amount.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "AmountTo",
            "in": "query",
            "description": "Matches payments of at most this amount.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
              "format": "double"
            }
          },
          {
            "name": "DatePaidFrom",
            "in": "query",
            "description": "Matches payments paid on or after this date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DatePaidTo",
            "in": "query",
            "description": "Matches payments paid on or before this date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateAddedFrom",
            "in": "query",
            "description": "Matches payments added on or after this UTC date and time.\r\n<ul><li>Use with `dateAddedTo` to read only what has been added since your last read.</li></ul>",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateAddedTo",
            "in": "query",
            "description": "Matches payments added on or before this UTC date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedFrom",
            "in": "query",
            "description": "Matches payments changed on or after this UTC date and time.\r\n<ul><li>Use with `dateChangedTo` to read only what has changed since your last read.</li></ul>",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateChangedTo",
            "in": "query",
            "description": "Matches payments changed on or before this UTC date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateTimePaidFrom",
            "in": "query",
            "description": "Matches payments paid on or after this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "DateTimePaidTo",
            "in": "query",
            "description": "Matches payments paid on or before this date and time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "AcknowledgedOnFrom",
            "in": "query",
            "description": "Matches payments acknowledged on or after this date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "AcknowledgedOnTo",
            "in": "query",
            "description": "Matches payments acknowledged on or before this date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "TransactionStatus",
            "in": "query",
            "description": "Matches payments with exactly this status.\r\n<ul><li>Every status is returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsActive",
            "in": "query",
            "description": "Matches active (`true`) or inactive (`false`) payments.\r\n<ul><li>Both are returned when the filter is not supplied.</li></ul>",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageNumber",
            "in": "query",
            "description": "The page of results to return, starting at 1. Defaults to the first page.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "UsePaging",
            "in": "query",
            "description": "Whether the results are returned a page at a time. Paging is on unless this is set to false, in which case every matching record is returned.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "PageSize",
            "in": "query",
            "description": "The number of records returned per page. Defaults to 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "format": "int32"
            }
          },
          {
            "name": "Include",
            "in": "query",
            "description": "One or more related resources to expand in the response, separated by commas.",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "enum": [
                  "allocations"
                ],
                "type": "string"
              }
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "description": "The field the results are sorted by.",
            "schema": {
              "enum": [
                "datePaid",
                "transactionNumber",
                "dateAdded",
                "dateChanged",
                "amount",
                "transactionStatus",
                "dateTimePaid",
                "acknowledgedOn",
                "constituentDescription",
                "constituentNumber",
                "campaign",
                "paymentMethod",
                "currency",
                "channel",
                "bankAccount",
                "acknowledgement",
                "reference",
                "payoutReference",
                "giftAidStatus",
                "giftAidAmountClaimed",
                "processingCostsAmount"
              ],
              "type": "string"
            }
          },
          {
            "name": "sortDirection",
            "in": "query",
            "description": "Ascending as default if not selected and sortBy selected",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The page of payments matching the filters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Transactions.TransactionApiResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "A filter, sort, paging or `include` value is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transactions.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessTransactionsRpis` permission.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The payments could not be retrieved."
          }
        }
      },
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Adds a transaction to a constituent.",
        "description": "A transaction is made up of a payment and one or more allocations of that payment, so\r\n`amount` must equal the sum of the allocation amounts. The payment and its allocations\r\nare created together: if any of them cannot be created, none of them is.\r\n<br /><br />\r\nA campaign and a payment method are required, as they are when a transaction is edited in\r\nthe CRM, but a fundraising page can supply either of them. The campaign is given by\r\n`campaignId`, or by `campaign` when exactly one campaign carries that name,\r\nwhether it is active or not.\r\nBoth `amount` and `datePaid` are required.\r\n<br /><br />\r\nAn allocation that does not name a product or fund takes the default product and fund of\r\nthe campaign. The currency falls back to your home currency. The allocation\r\n`quantity` is recorded alongside the amount and never multiplies it.\r\nRequires a user in the `Admin` or `Standard` role, holding the\r\n`AccessTransactionsRpis` permission. System callers are not subject to these checks.\r\n<br /><br />\r\nThe payment and every allocation take their own number from your transaction counter, so\r\nthe numbers returned are consecutive rather than shared.\r\n<br /><br />\r\nThe donor is given in exactly one of three ways: `constituentId` for a constituent\r\nthat already exists, `newConstituent` to create one along with the transaction, or\r\n`isAnonymousTransaction` for a transaction with no donor at all. The ID of the donor\r\nis returned as `constituentId`, and is null for an anonymous transaction. An\r\nallocation `beneficiaryConstituentId` is independent of the donor and remains valid on\r\nan anonymous transaction.\r\n<br /><br />\r\nA constituent named in `newConstituent` is validated with the transaction, so its\r\nerrors are returned in the same response. It is created only once the rest of the request\r\nhas been found valid, so a rejected request never leaves a constituent behind. It is\r\ncreated before the transaction is written, however, and is deliberately not removed again\r\nif writing the transaction then fails — the same behaviour as the legacy API.\r\n<br /><br />`newConstituent` follows the contract of `POST /v1/constituents`: its contact\r\ndetail properties are stored on the main contact details of the constituent it creates, its\r\nkeep in touch preferences are given as `channelPreferences` with\r\n`preferenceAllowed` per channel, and tags are not accepted. A group type rejects the\r\nperson properties and takes the individual to create as its main contact in the nested\r\n`newConstituent.mainContact` object, which shares nothing with the group; that\r\nindividual is created as the main contact of the group while the transaction stays\r\nattached to the group returned as `constituentId`. Errors inside the object are\r\nreturned against `NewConstituent.MainContact.&lt;field&gt;`.\r\n<br /><br />`newConstituent.nationalIDNumber` is stored as it is given, as it is when a\r\nconstituent is created on its own: the `AccessNationalIdentity` role is only needed to\r\nread a national identification number back or to change one.",
        "operationId": "CreateTransaction",
        "requestBody": {
          "description": "Cancels the request.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Transactions.CreateTransactionApiRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "The transaction that was created, described the same way `GET /v1/transactions/{transactionId}` describes it, with its location in the `Location` header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transactions.CreatedTransactionApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid, for example the constituent was not found, more than one donor was given, the allocations do not add up to the amount or a lookup value is unknown. Every validation error of the request is returned together, including those of `newConstituent`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transactions.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller is not in the `Admin` or `Standard` role, or does not hold the `AccessTransactionsRpis` permission.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction could not be created."
          }
        }
      }
    },
    "/v1/transactions/{transactionId}": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Retrieves one of your payments.",
        "description": "Only payments are served: an identifier of an allocation, of a payment of another Donorfy\r\ninstance, or of nothing at all, all return 404.\r\n<br /><br />\r\nThe allocations splitting the payment across products and funds are always returned, and\r\nare an empty array when the payment has none. They are read independently of the payment's\r\n`isActive` and `transactionStatus`, and are ordered by transaction number.\r\n<br /><br />`include=trackingCodes` expands the UTM tracking codes captured for the payment,\r\nfalling back to those of the constituent that paid when the payment carries none of its\r\nown, which is where historic codes are held. `include=softCredits` expands the\r\nconstituents soft credited with the payment. Both are omitted from the response entirely\r\nwhen they are not asked for.\r\n<br /><br />\r\nRequires the `AccessTransactionsRpis` permission.",
        "operationId": "GetTransactionById",
        "parameters": [
          {
            "name": "transactionId",
            "in": "path",
            "description": "Unique identifier of the payment to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Include",
            "in": "query",
            "description": "One or more related resources to expand in the response, separated by commas.",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "enum": [
                  "trackingCodes",
                  "softCredits"
                ],
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The payment, its allocations and the related resources asked for.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transactions.TransactionDetailApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The identifier of the payment is empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transactions.InvalidRequest"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessTransactionsRpis` permission.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No payment with that identifier exists for this Donorfy instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The payment could not be retrieved."
          }
        }
      }
    },
    "/v1/transactions/defaults": {
      "get": {
        "tags": [
          "Hidden"
        ],
        "summary": "Gets the transaction entry defaults of the Donorfy instance.",
        "description": "A single object, not a paged list. All nine defaults are always returned: a default is\r\n`null` when it is not configured or when the value it names no longer exists, and\r\nevery default is `null` when the instance holds no transaction defaults at all —\r\nthat is still a 200. The two acknowledgement\r\ndefaults are separate properties even though both name an acknowledgement type. A default\r\ncan be configured but inactive; it is still returned with `isActive` set to\r\n`false`.\r\n<br /><br />\r\nThis endpoint serves the transaction entry screens of a Donorfy client, so it is\r\ndeliberately kept out of the public OpenAPI document.",
        "operationId": "GetTransactionDefaults",
        "responses": {
          "200": {
            "description": "The transaction entry defaults of the instance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transactions.TransactionDefaultsApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "The request is not authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The caller does not hold the `AccessTransactionsRpis` permission.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "The transaction entry defaults could not be read."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AddressLookup.AddressApiResponse": {
        "type": "object",
        "properties": {
          "addressLine1": {
            "type": "string",
            "description": "First line of the address.",
            "nullable": true,
            "example": "1 High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "Second line of the address.",
            "nullable": true,
            "example": "Clifton"
          },
          "town": {
            "type": "string",
            "description": "Town or city of the address.",
            "nullable": true,
            "example": "Bristol"
          },
          "county": {
            "type": "string",
            "description": "County, state or province of the address.",
            "nullable": true,
            "example": "Avon"
          },
          "postalCode": {
            "type": "string",
            "description": "Postcode or zip code of the address.",
            "nullable": true,
            "example": "BS1 1AA"
          },
          "country": {
            "type": "string",
            "description": "Name of the country of the address.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House or building number of the address.",
            "nullable": true,
            "example": "1"
          },
          "buildingName": {
            "type": "string",
            "description": "Name of the building of the address.",
            "nullable": true,
            "example": "Clifton House"
          },
          "subBuilding": {
            "type": "string",
            "description": "Sub-building, such as a flat or apartment, of the address.",
            "nullable": true,
            "example": "Flat 2"
          },
          "street": {
            "type": "string",
            "description": "Street of the address.",
            "nullable": true,
            "example": "High Street"
          }
        },
        "description": "The full address behind an address candidate."
      },
      "AddressLookup.AddressCandidateApiResponse": {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier of the candidate, passed back to `retrieve` to get the full address, or as\r\nthe `container` of the next search when the candidate is not an address.",
            "example": "GB|RM|ENG|BS1-BRISTOL"
          },
          "isAddress": {
            "type": "boolean",
            "description": "Whether the candidate is a complete address.\r\n<ul><li>`false` when the candidate groups further addresses; search into it by passing its\r\n`id` as the `container`.</li></ul>",
            "example": true
          },
          "text": {
            "type": "string",
            "description": "The candidate as it is shown to the user.",
            "nullable": true,
            "example": "Bristol, BS1"
          },
          "description": {
            "type": "string",
            "description": "The remainder of the address, shown next to the candidate.",
            "nullable": true,
            "example": "Bristol - 128 Addresses"
          }
        },
        "description": "An address candidate matching what the user has typed."
      },
      "AddressLookup.AddressLookupSettingsApiResponse": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean",
            "description": "Whether the instance can look addresses up, so whether a client should offer the address\r\nsearch at all. When `false` the search and retrieve endpoints answer with a 404.",
            "example": true
          }
        },
        "description": "How address lookup is set up for the instance. The instance's Loqate key stays on the server\r\nand is never part of this response."
      },
      "AddressLookup.InvalidRequest": {
        "required": [
          "message",
          "errors"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Summary of why the request was rejected."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AddressLookup.ValidationItem"
            },
            "description": "The individual validation failures of the request; empty when the failure is not specific to a\r\nsingle field."
          }
        },
        "description": "The body returned when a request is rejected because it is not valid."
      },
      "AddressLookup.ValidationItem": {
        "required": [
          "message",
          "field"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Description of what is wrong with the value."
          },
          "field": {
            "type": "string",
            "description": "Name of the field the failure relates to."
          }
        },
        "description": "A single validation failure of a request."
      },
      "ApiSortDirection": {
        "enum": [
          "ascending",
          "descending"
        ],
        "type": "string",
        "description": "Values: ascending, descending. Send the value, not the integer it stands for. Integers are still accepted for compatibility: ascending = 1, descending = 2."
      },
      "Campaign.CampaignApiSort": {
        "enum": [
          "description",
          "year",
          "dateAdded",
          "campaignNumber"
        ],
        "type": "string",
        "description": "The fields a list of campaigns can be sorted by.\n\nValues: description, year, dateAdded, campaignNumber. Send the value, not the integer it stands for. Integers are still accepted for compatibility: description = 0, year = 1, dateAdded = 2, campaignNumber = 3."
      },
      "Campaign.CampaignDetailApiResponse": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "string",
            "description": "Unique identifier of the campaign, exposed as `campaignId`.\r\n<ul><li>Assigned by Donorfy when the campaign is created.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaignNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the campaign.\r\n<ul><li>Assigned by Donorfy; used as the human readable reference of the campaign.</li></ul>",
            "format": "int64",
            "example": 274
          },
          "description": {
            "type": "string",
            "description": "Name of the campaign.",
            "nullable": true,
            "example": "Winter Appeal 2025"
          },
          "campaignType": {
            "type": "string",
            "description": "Type of the campaign.",
            "nullable": true,
            "example": "Appeal"
          },
          "year": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Year the campaign runs in.",
            "format": "int32",
            "example": 2025
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the campaign is active.\r\n<ul><li>`false` once the campaign has been closed.</li></ul>",
            "nullable": true,
            "example": true
          },
          "isEvent": {
            "type": "boolean",
            "description": "Whether the campaign is an event rather than an ordinary campaign.",
            "nullable": true,
            "example": false
          },
          "notes": {
            "type": "string",
            "description": "Free text notes recorded against the campaign.",
            "nullable": true,
            "example": "Mailed to all lapsed donors in November."
          },
          "defaultProduct": {
            "type": "string",
            "description": "Description of the lookup value for the product transactions of the campaign default to.",
            "nullable": true,
            "example": "General Donation"
          },
          "defaultFund": {
            "type": "string",
            "description": "Description of the lookup value for the fund transactions of the campaign are allocated to\r\nby default.",
            "nullable": true,
            "example": "Unrestricted"
          },
          "channelId": {
            "type": "string",
            "description": "Identifier of the channel the campaign is run through.",
            "format": "uuid",
            "nullable": true,
            "example": "3c4d5e6f-7a8b-4c9d-8e1f-2a3b4c5d6e7f"
          },
          "channel": {
            "type": "string",
            "description": "Description of the lookup value for the channel the campaign is run through.",
            "nullable": true,
            "example": "Direct Mail"
          },
          "constituentsBudget": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Number of constituents the campaign is budgeted to recruit.",
            "format": "double",
            "example": 500
          },
          "transactionsBudget": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Income the campaign is budgeted to raise, in your home currency.",
            "format": "double",
            "example": 25000.00
          },
          "expensesTotal": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Total expenses recorded against the campaign, in your home currency.",
            "format": "double",
            "example": 3200.50
          },
          "audienceSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Number of people the campaign was sent to or aimed at.",
            "format": "double",
            "example": 12000
          },
          "ownerId": {
            "type": "string",
            "description": "Identifier of the user who owns the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "9c1f1f5e-4a1b-4f4c-9c0e-2f9a1b3c4d5e"
          },
          "owner": {
            "type": "string",
            "description": "Full name of the user who owns the campaign.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "contactConstituentId": {
            "type": "string",
            "description": "Identifier of the constituent who is the contact for the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaignMembersListId": {
            "type": "string",
            "description": "Identifier of the list definition holding the members of the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "6b3f2c1d-8e7a-4b2c-9d1e-5f6a7b8c9d0e"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the campaign was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T09:30:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the campaign was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          }
        },
        "description": "A single fundraising campaign, returned when one campaign is retrieved."
      },
      "Campaign.CampaignListApiResponse": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "string",
            "description": "Unique identifier of the campaign, exposed as `campaignId`.\r\n<ul><li>Assigned by Donorfy when the campaign is created.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaignNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the campaign.\r\n<ul><li>Assigned by Donorfy; used as the human readable reference of the campaign.</li></ul>",
            "format": "int64",
            "example": 274
          },
          "description": {
            "type": "string",
            "description": "Name of the campaign.",
            "nullable": true,
            "example": "Winter Appeal 2025"
          },
          "campaignType": {
            "type": "string",
            "description": "Type of the campaign.",
            "nullable": true,
            "example": "Appeal"
          },
          "year": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Year the campaign runs in.",
            "format": "int32",
            "example": 2025
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the campaign is active.\r\n<ul><li>`false` once the campaign has been closed.</li></ul>",
            "nullable": true,
            "example": true
          },
          "isEvent": {
            "type": "boolean",
            "description": "Whether the campaign is an event rather than an ordinary campaign.",
            "nullable": true,
            "example": false
          },
          "notes": {
            "type": "string",
            "description": "Free text notes recorded against the campaign.",
            "nullable": true,
            "example": "Mailed to all lapsed donors in November."
          },
          "defaultProduct": {
            "type": "string",
            "description": "Description of the lookup value for the product transactions of the campaign default to.",
            "nullable": true,
            "example": "General Donation"
          },
          "defaultFund": {
            "type": "string",
            "description": "Description of the lookup value for the fund transactions of the campaign are allocated to\r\nby default.",
            "nullable": true,
            "example": "Unrestricted"
          },
          "channelId": {
            "type": "string",
            "description": "Identifier of the channel the campaign is run through.",
            "format": "uuid",
            "nullable": true,
            "example": "3c4d5e6f-7a8b-4c9d-8e1f-2a3b4c5d6e7f"
          },
          "channel": {
            "type": "string",
            "description": "Description of the lookup value for the channel the campaign is run through.",
            "nullable": true,
            "example": "Direct Mail"
          },
          "constituentsBudget": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Number of constituents the campaign is budgeted to recruit.",
            "format": "double",
            "example": 500
          },
          "transactionsBudget": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Income the campaign is budgeted to raise, in your home currency.",
            "format": "double",
            "example": 25000.00
          },
          "expensesTotal": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Total expenses recorded against the campaign, in your home currency.",
            "format": "double",
            "example": 3200.50
          },
          "audienceSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Number of people the campaign was sent to or aimed at.",
            "format": "double",
            "example": 12000
          },
          "ownerId": {
            "type": "string",
            "description": "Identifier of the user who owns the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "9c1f1f5e-4a1b-4f4c-9c0e-2f9a1b3c4d5e"
          },
          "owner": {
            "type": "string",
            "description": "Full name of the user who owns the campaign.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "contactConstituentId": {
            "type": "string",
            "description": "Identifier of the constituent who is the contact for the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaignMembersListId": {
            "type": "string",
            "description": "Identifier of the list definition holding the members of the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "6b3f2c1d-8e7a-4b2c-9d1e-5f6a7b8c9d0e"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the campaign was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T09:30:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the campaign was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          }
        },
        "description": "A fundraising campaign — the appeal, event or other initiative that income, activities and\r\nconstituent recruitment are attributed to."
      },
      "Campaign.InvalidRequest": {
        "required": [
          "message",
          "errors"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Summary of why the request was rejected."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Campaign.ValidationItem"
            },
            "description": "The individual validation failures of the request; empty when the failure is not specific to a\r\nsingle field."
          }
        },
        "description": "The body returned when a request is rejected because it is not valid."
      },
      "Campaign.ValidationItem": {
        "required": [
          "message",
          "field"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Description of what is wrong with the value."
          },
          "field": {
            "type": "string",
            "description": "Name of the field the failure relates to."
          }
        },
        "description": "A single validation failure of a request."
      },
      "Constituent.ActivityApiResponse": {
        "type": "object",
        "properties": {
          "activityId": {
            "type": "string",
            "description": "Unique identifier of the activity.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "activityNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number Donorfy gave the activity.",
            "format": "int64",
            "example": 10432
          },
          "constituentId": {
            "type": "string",
            "description": "Constituent the activity is recorded against.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "activityTypeId": {
            "type": "string",
            "description": "Identifier of the type of the activity.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "activityType": {
            "type": "string",
            "description": "Description of the type of the activity.",
            "nullable": true,
            "example": "Phone Call"
          },
          "activityDate": {
            "type": "string",
            "description": "Date of the activity.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "campaignId": {
            "type": "string",
            "description": "Campaign the activity is recorded against.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaign": {
            "type": "string",
            "description": "Description of the campaign the activity is recorded against.",
            "nullable": true,
            "example": "Summer Appeal"
          },
          "isConfidential": {
            "type": "boolean",
            "description": "Whether the activity is confidential.",
            "nullable": true,
            "example": false
          },
          "showAlert": {
            "type": "boolean",
            "description": "Whether the activity is shown as an alert on the constituent's record in Donorfy.",
            "nullable": true,
            "example": false
          },
          "notes": {
            "type": "string",
            "description": "Notes about the activity.",
            "nullable": true,
            "example": "Called to thank them for their donation."
          },
          "code1": {
            "type": "string",
            "description": "Value of user-defined code field 1.",
            "nullable": true,
            "example": "Gold"
          },
          "code2": {
            "type": "string",
            "description": "Value of user-defined code field 2.",
            "nullable": true,
            "example": "Gold"
          },
          "code3": {
            "type": "string",
            "description": "Value of user-defined code field 3.",
            "nullable": true,
            "example": "Gold"
          },
          "code4": {
            "type": "string",
            "description": "Value of user-defined code field 4.",
            "nullable": true,
            "example": "Gold"
          },
          "code5": {
            "type": "string",
            "description": "Value of user-defined code field 5.",
            "nullable": true,
            "example": "Gold"
          },
          "code6": {
            "type": "string",
            "description": "Value of user-defined code field 6.",
            "nullable": true,
            "example": "Gold"
          },
          "code7": {
            "type": "string",
            "description": "Value of user-defined code field 7.",
            "nullable": true,
            "example": "Gold"
          },
          "code8": {
            "type": "string",
            "description": "Value of user-defined code field 8.",
            "nullable": true,
            "example": "Gold"
          },
          "code9": {
            "type": "string",
            "description": "Value of user-defined code field 9.",
            "nullable": true,
            "example": "Gold"
          },
          "code10": {
            "type": "string",
            "description": "Value of user-defined code field 10.",
            "nullable": true,
            "example": "Gold"
          },
          "yesNo1": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 1.",
            "nullable": true,
            "example": true
          },
          "yesNo2": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 2.",
            "nullable": true,
            "example": true
          },
          "yesNo3": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 3.",
            "nullable": true,
            "example": true
          },
          "yesNo4": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 4.",
            "nullable": true,
            "example": true
          },
          "yesNo5": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 5.",
            "nullable": true,
            "example": true
          },
          "yesNo6": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 6.",
            "nullable": true,
            "example": true
          },
          "yesNo7": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 7.",
            "nullable": true,
            "example": true
          },
          "yesNo8": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 8.",
            "nullable": true,
            "example": true
          },
          "yesNo9": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 9.",
            "nullable": true,
            "example": true
          },
          "yesNo10": {
            "type": "boolean",
            "description": "Value of user-defined yes/no field 10.",
            "nullable": true,
            "example": true
          },
          "number1": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 1.",
            "format": "double",
            "example": 12.5
          },
          "number2": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 2.",
            "format": "double",
            "example": 12.5
          },
          "number3": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 3.",
            "format": "double",
            "example": 12.5
          },
          "number4": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 4.",
            "format": "double",
            "example": 12.5
          },
          "number5": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 5.",
            "format": "double",
            "example": 12.5
          },
          "number6": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 6.",
            "format": "double",
            "example": 12.5
          },
          "number7": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 7.",
            "format": "double",
            "example": 12.5
          },
          "number8": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 8.",
            "format": "double",
            "example": 12.5
          },
          "number9": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 9.",
            "format": "double",
            "example": 12.5
          },
          "number10": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Value of user-defined number field 10.",
            "format": "double",
            "example": 12.5
          },
          "date1": {
            "type": "string",
            "description": "Value of user-defined date field 1.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date2": {
            "type": "string",
            "description": "Value of user-defined date field 2.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date3": {
            "type": "string",
            "description": "Value of user-defined date field 3.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date4": {
            "type": "string",
            "description": "Value of user-defined date field 4.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date5": {
            "type": "string",
            "description": "Value of user-defined date field 5.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date6": {
            "type": "string",
            "description": "Value of user-defined date field 6.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date7": {
            "type": "string",
            "description": "Value of user-defined date field 7.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date8": {
            "type": "string",
            "description": "Value of user-defined date field 8.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date9": {
            "type": "string",
            "description": "Value of user-defined date field 9.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date10": {
            "type": "string",
            "description": "Value of user-defined date field 10.",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "linkUrl": {
            "type": "string",
            "description": "Web address related to the activity, shown as a link on the activity in Donorfy.",
            "nullable": true,
            "example": "https://www.example.org/events/summer-gala"
          },
          "externalReference1": {
            "type": "string",
            "description": "External reference 1 of the activity.",
            "nullable": true,
            "example": "EXT-REF-1"
          },
          "externalReference2": {
            "type": "string",
            "description": "External reference 2 of the activity.",
            "nullable": true,
            "example": "EXT-REF-2"
          },
          "externalReference3": {
            "type": "string",
            "description": "External reference 3 of the activity.",
            "nullable": true,
            "example": "EXT-REF-3"
          },
          "externalReference4": {
            "type": "string",
            "description": "External reference 4 of the activity.",
            "nullable": true,
            "example": "EXT-REF-4"
          },
          "externalReference5": {
            "type": "string",
            "description": "External reference 5 of the activity.",
            "nullable": true,
            "example": "EXT-REF-5"
          },
          "utmSource": {
            "type": "string",
            "description": "UTM source tracking code of the activity.",
            "nullable": true,
            "example": "newsletter"
          },
          "utmMedium": {
            "type": "string",
            "description": "UTM medium tracking code of the activity.",
            "nullable": true,
            "example": "email"
          },
          "utmTerm": {
            "type": "string",
            "description": "UTM term tracking code of the activity.",
            "nullable": true,
            "example": "donate"
          },
          "utmContent": {
            "type": "string",
            "description": "UTM content tracking code of the activity.",
            "nullable": true,
            "example": "header-link"
          },
          "utmCampaign": {
            "type": "string",
            "description": "UTM campaign tracking code of the activity.",
            "nullable": true,
            "example": "summer-appeal"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the activity is active.",
            "nullable": true,
            "example": true
          },
          "enteredByUser": {
            "type": "string",
            "description": "Name of the user who recorded the activity.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "enteredByUserId": {
            "type": "string",
            "description": "Identifier of the user who recorded the activity.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time, in UTC, the activity was recorded.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-30T10:15:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time, in UTC, the activity was last changed.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-09-30T10:15:00Z"
          }
        },
        "description": "An activity recorded against a constituent, such as a phone call, meeting or letter."
      },
      "Constituent.ChannelPermissionApiRequest": {
        "type": "object",
        "properties": {
          "preferenceAllowed": {
            "type": "boolean",
            "description": "Whether the constituent may be contacted through the channel.\r\n<ul><li>Optional; a channel left out, like the whole object when it is omitted, is recorded unconfirmed and reads back as `null`.</li><li>Supplying `true` or `false` confirms the preference, so it reads back as given.</li></ul>",
            "nullable": true,
            "example": true
          },
          "campaignId": {
            "type": "string",
            "description": "The identifier of the campaign the preference is attributed to.\r\n<ul><li>Optional; defaults to the recruitment campaign of the constituent when the preference is confirmed by `preferenceAllowed`, and is not recorded at all when it is not.</li><li>Takes precedence over `campaign`.</li><li>Must be an existing campaign.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9fd8f40c-6df1-ec11-b5cf-0003ff444e27"
          },
          "campaign": {
            "type": "string",
            "description": "The name of the campaign the preference is attributed to.\r\n<ul><li>Optional; accepted when creating a constituent only, and never returned. The preference reads back with `campaignId`.</li><li>The identifier, or the name, of an existing campaign. A value that is a GUID is resolved by identifier, anything else by name.</li><li>Ignored when `campaignId` is supplied as well.</li></ul>",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "dateAdded": {
            "type": "string",
            "description": "When the preference was given, for loading preferences recorded before today.\r\n<ul><li>Optional; defaults to the moment the constituent is created.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2024-03-12T09:30:00Z"
          }
        },
        "description": "The keep in touch preference recorded for one communication channel."
      },
      "Constituent.ChannelPreferenceApiResponse": {
        "type": "object",
        "properties": {
          "channelPreferenceId": {
            "type": "string",
            "description": "Unique identifier of the channel preference.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "channelName": {
            "type": "string",
            "description": "Name of the channel the preference applies to.",
            "example": "Email"
          },
          "preferenceAllowed": {
            "type": "boolean",
            "description": "Whether the constituent may be contacted through the channel. Null means the constituent's\r\nwishes are not known because the preference is unconfirmed, not that contact has been refused.",
            "nullable": true,
            "example": true
          },
          "campaignId": {
            "type": "string",
            "description": "Identifier of the campaign the preference was last attributed to, where one was recorded.",
            "format": "uuid",
            "nullable": true,
            "example": "9c1b2f42-4c60-4c5f-9c5a-8f4c1d0e7b21"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the preference was created.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-15T09:30:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the preference was last changed.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-03-02T14:05:00Z"
          }
        },
        "description": "The permission a constituent has given, or withheld, for being contacted through a channel."
      },
      "Constituent.ChannelPreferencesApiRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for email.",
            "nullable": true
          },
          "phone": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for phone.",
            "nullable": true
          },
          "mail": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for post.",
            "nullable": true
          },
          "sms": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for SMS.",
            "nullable": true
          }
        },
        "description": "The communication channels the constituent may be contacted on."
      },
      "Constituent.ConstituentApiInclude": {
        "enum": [
          "contactDetails",
          "trackingCodes",
          "tags",
          "channelPreferences",
          "givingSummary"
        ],
        "type": "string",
        "description": "The related resources that can be expanded when retrieving a constituent.\n\nValues: contactDetails, trackingCodes, tags, channelPreferences, givingSummary. Send the value, not the integer it stands for. Integers are still accepted for compatibility: contactDetails = 0, trackingCodes = 1, tags = 2, channelPreferences = 3, givingSummary = 4."
      },
      "Constituent.ConstituentApiResponse": {
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "Unique identifier of the constituent.\r\n<ul><li>Assigned by Donorfy when the constituent is created.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the constituent.\r\n<ul><li>Assigned by Donorfy; used as the human readable reference of the constituent.</li></ul>",
            "format": "int64",
            "example": 10432
          },
          "constituentType": {
            "type": "string",
            "description": "Type of the constituent, as described in the `Constituent Types` lookup.",
            "nullable": true,
            "example": "Individual"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the constituent is active.\r\n<ul><li>`false` once the constituent has been archived.</li></ul>",
            "nullable": true,
            "example": true
          },
          "title": {
            "type": "string",
            "description": "Title of the person.",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "First name of the person.",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "description": "Last name of the person.",
            "nullable": true,
            "example": "Smith"
          },
          "middleName": {
            "type": "string",
            "description": "Middle name of the person.",
            "nullable": true,
            "example": "Elizabeth"
          },
          "prefix": {
            "type": "string",
            "description": "Name prefix used when addressing the constituent.",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "Letters or honours that follow the name of the constituent.",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "Previous name of the constituent.",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "Informal or alternative name the constituent is known by.",
            "nullable": true,
            "example": "Janey"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "Date of birth of the constituent.\r\n<ul><li>Only held for constituents that are not a group.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "gender": {
            "type": "string",
            "description": "Gender of the constituent, as described in the `Genders` lookup.",
            "nullable": true,
            "example": "Female"
          },
          "organisationName": {
            "type": "string",
            "description": "Name of the organisation, trust or other group.\r\n<ul><li>Only held for group constituent types.</li></ul>",
            "nullable": true,
            "example": "The Access Group"
          },
          "description": {
            "type": "string",
            "description": "Description Donorfy holds for the constituent, used as its display name across the CRM.\r\n<ul><li>The organisation name for a group, and `{prefix} {lastName}, {title} {firstName}`\r\nfor an individual.</li><li>Maintained by Donorfy from the name properties of the constituent and read only.</li></ul>",
            "nullable": true,
            "example": "Dr Smith, Mrs Jane"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "National identification number of the constituent, for example a National Insurance number.\r\n<ul><li>For an Access Identity user without the `AccessNationalIdentity` role the value is replaced with `Insufficient Permissions`; system integrations authenticating with Basic auth always receive the value.</li><li>For the same reason, the value cannot be used to filter or sort a collection unless the caller holds that role.</li></ul>",
            "nullable": true,
            "example": "QQ123456C"
          },
          "jobTitle": {
            "type": "string",
            "description": "Job title held on the main contact details of the constituent.",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "Department held on the main contact details of the constituent.",
            "nullable": true,
            "example": "Development"
          },
          "salutation": {
            "type": "string",
            "description": "Salutation used when writing to the constituent, from the main contact details.",
            "nullable": true,
            "example": "Dear Jane"
          },
          "labelName": {
            "type": "string",
            "description": "Name used on labels and envelopes, from the main contact details of the constituent.",
            "nullable": true,
            "example": "Mrs Jane Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House name or number of the main address of the constituent.",
            "nullable": true,
            "example": "42"
          },
          "addressLine1": {
            "type": "string",
            "description": "First line of the main address of the constituent.",
            "nullable": true,
            "example": "42 High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "Second line of the main address of the constituent.",
            "nullable": true,
            "example": "Riverside"
          },
          "town": {
            "type": "string",
            "description": "Town or city of the main address of the constituent.",
            "nullable": true,
            "example": "Loughborough"
          },
          "county": {
            "type": "string",
            "description": "County of the main address of the constituent.",
            "nullable": true,
            "example": "Leicestershire"
          },
          "postalCode": {
            "type": "string",
            "description": "Postal code of the main address of the constituent.",
            "nullable": true,
            "example": "LE11 1AA"
          },
          "country": {
            "type": "string",
            "description": "Country of the main address of the constituent, as described in the `Countries` lookup.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "First landline phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "01234 567890"
          },
          "phone2": {
            "type": "string",
            "description": "Second landline phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "01234 567891"
          },
          "mobilePhone": {
            "type": "string",
            "description": "Mobile phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "07700 900123"
          },
          "email1Address": {
            "type": "string",
            "description": "First email address held on the main contact details of the constituent.",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "Format the first email address should be sent in.",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "Second email address held on the main contact details of the constituent.",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "Format the second email address should be sent in.",
            "nullable": true,
            "example": "Text"
          },
          "linkedToConstituentId": {
            "type": "string",
            "description": "Constituent the main address is shared with.\r\n<ul><li>Set when the main contact details of the constituent link to another constituent; the\r\naddress properties then come from that constituent while the phone numbers, email\r\naddresses and salutation stay with this one.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9f1c1e8e-0d0e-4c4d-9f6a-2b7c9f3e51aa"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name may be swapped when Donorfy detects they were entered the wrong way round.",
            "nullable": true,
            "example": false
          },
          "isGroup": {
            "type": "boolean",
            "description": "Whether the constituent is a group, such as an organisation or trust, rather than an individual.\r\n<ul><li>Derived from the constituent type.</li></ul>",
            "nullable": true,
            "example": false
          },
          "archiveDate": {
            "type": "string",
            "description": "Date the constituent was archived.\r\n<ul><li>Empty while the constituent is active.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-15T09:30:00Z"
          },
          "archiveReason": {
            "type": "string",
            "description": "Reason the constituent was archived, as described in the `Archive Reasons` lookup.",
            "nullable": true,
            "example": "Deceased"
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the constituent is excluded from Gift Aid claims.",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "Identifier of the constituent in the system that owns the data outside Donorfy.",
            "nullable": true,
            "example": "CRM-00012345"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "Campaign the constituent was recruited by.",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "Identifier of the campaign the constituent was recruited by.",
            "format": "uuid",
            "nullable": true,
            "example": "6f9619ff-8b86-d011-b42d-00cf4fc964ff"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the constituent was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-05T14:22:31Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the constituent was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-02-11T08:05:09Z"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.TagApiResponse"
            },
            "description": "Tags allocated to the constituent, restricted to the tag categories the caller is\r\npermitted to see.\r\n<ul><li>Returned only when an `include` asks for them: the pinned tags with\r\n`include=pinnedTags` when listing constituents, every tag with `include=tags`\r\nwhen retrieving one.</li><li>Empty when the constituent has no tags the caller may see.</li></ul>",
            "nullable": true
          }
        },
        "description": "A constituent — a person, organisation or group held in the CRM."
      },
      "Constituent.ConstituentApiSort": {
        "enum": [
          "constituentNumber",
          "lastName",
          "firstName",
          "organisationName",
          "dateOfBirth",
          "nationalIDNumber",
          "archiveDate",
          "dateAdded",
          "dateChanged",
          "constituentType",
          "gender",
          "archiveReason",
          "recruitmentCampaign",
          "jobTitle",
          "department",
          "salutation",
          "labelName",
          "houseBuildingNumber",
          "addressLine1",
          "addressLine2",
          "town",
          "county",
          "postalCode",
          "country",
          "phone1",
          "phone2",
          "mobilePhone",
          "email1Address",
          "email1Format",
          "email2Address",
          "email2Format",
          "linkedToConstituentId"
        ],
        "type": "string",
        "description": "The fields a list of constituents can be sorted by.\n\nValues: constituentNumber, lastName, firstName, organisationName, dateOfBirth, nationalIDNumber, archiveDate, dateAdded, dateChanged, constituentType, gender, archiveReason, recruitmentCampaign, jobTitle, department, salutation, labelName, houseBuildingNumber, addressLine1, addressLine2, town, county, postalCode, country, phone1, phone2, mobilePhone, email1Address, email1Format, email2Address, email2Format, linkedToConstituentId. Send the value, not the integer it stands for. Integers are still accepted for compatibility: constituentNumber = 0, lastName = 1, firstName = 2, organisationName = 3, dateOfBirth = 4, nationalIDNumber = 5, archiveDate = 6, dateAdded = 7, dateChanged = 8, constituentType = 9, gender = 10, archiveReason = 11, recruitmentCampaign = 12, jobTitle = 13, department = 14, salutation = 15, labelName = 16, houseBuildingNumber = 17, addressLine1 = 18, addressLine2 = 19, town = 20, county = 21, postalCode = 22, country = 23, phone1 = 24, phone2 = 25, mobilePhone = 26, email1Address = 27, email1Format = 28, email2Address = 29, email2Format = 30, linkedToConstituentId = 31."
      },
      "Constituent.ConstituentDetailApiResponse": {
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "Unique identifier of the constituent.\r\n<ul><li>Assigned by Donorfy when the constituent is created.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the constituent.\r\n<ul><li>Assigned by Donorfy; used as the human readable reference of the constituent.</li></ul>",
            "format": "int64",
            "example": 10432
          },
          "constituentType": {
            "type": "string",
            "description": "Type of the constituent, as described in the `Constituent Types` lookup.",
            "nullable": true,
            "example": "Individual"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the constituent is active.\r\n<ul><li>`false` once the constituent has been archived.</li></ul>",
            "nullable": true,
            "example": true
          },
          "title": {
            "type": "string",
            "description": "Title of the person.",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "First name of the person.",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "description": "Last name of the person.",
            "nullable": true,
            "example": "Smith"
          },
          "middleName": {
            "type": "string",
            "description": "Middle name of the person.",
            "nullable": true,
            "example": "Elizabeth"
          },
          "prefix": {
            "type": "string",
            "description": "Name prefix used when addressing the constituent.",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "Letters or honours that follow the name of the constituent.",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "Previous name of the constituent.",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "Informal or alternative name the constituent is known by.",
            "nullable": true,
            "example": "Janey"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "Date of birth of the constituent.\r\n<ul><li>Only held for constituents that are not a group.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "gender": {
            "type": "string",
            "description": "Gender of the constituent, as described in the `Genders` lookup.",
            "nullable": true,
            "example": "Female"
          },
          "organisationName": {
            "type": "string",
            "description": "Name of the organisation, trust or other group.\r\n<ul><li>Only held for group constituent types.</li></ul>",
            "nullable": true,
            "example": "The Access Group"
          },
          "description": {
            "type": "string",
            "description": "Description Donorfy holds for the constituent, used as its display name across the CRM.\r\n<ul><li>The organisation name for a group, and `{prefix} {lastName}, {title} {firstName}`\r\nfor an individual.</li><li>Maintained by Donorfy from the name properties of the constituent and read only.</li></ul>",
            "nullable": true,
            "example": "Dr Smith, Mrs Jane"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "National identification number of the constituent, for example a National Insurance number.\r\n<ul><li>For an Access Identity user without the `AccessNationalIdentity` role the value is replaced with `Insufficient Permissions`; system integrations authenticating with Basic auth always receive the value.</li><li>For the same reason, the value cannot be used to filter or sort a collection unless the caller holds that role.</li></ul>",
            "nullable": true,
            "example": "QQ123456C"
          },
          "jobTitle": {
            "type": "string",
            "description": "Job title held on the main contact details of the constituent.",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "Department held on the main contact details of the constituent.",
            "nullable": true,
            "example": "Development"
          },
          "salutation": {
            "type": "string",
            "description": "Salutation used when writing to the constituent, from the main contact details.",
            "nullable": true,
            "example": "Dear Jane"
          },
          "labelName": {
            "type": "string",
            "description": "Name used on labels and envelopes, from the main contact details of the constituent.",
            "nullable": true,
            "example": "Mrs Jane Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House name or number of the main address of the constituent.",
            "nullable": true,
            "example": "42"
          },
          "addressLine1": {
            "type": "string",
            "description": "First line of the main address of the constituent.",
            "nullable": true,
            "example": "42 High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "Second line of the main address of the constituent.",
            "nullable": true,
            "example": "Riverside"
          },
          "town": {
            "type": "string",
            "description": "Town or city of the main address of the constituent.",
            "nullable": true,
            "example": "Loughborough"
          },
          "county": {
            "type": "string",
            "description": "County of the main address of the constituent.",
            "nullable": true,
            "example": "Leicestershire"
          },
          "postalCode": {
            "type": "string",
            "description": "Postal code of the main address of the constituent.",
            "nullable": true,
            "example": "LE11 1AA"
          },
          "country": {
            "type": "string",
            "description": "Country of the main address of the constituent, as described in the `Countries` lookup.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "First landline phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "01234 567890"
          },
          "phone2": {
            "type": "string",
            "description": "Second landline phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "01234 567891"
          },
          "mobilePhone": {
            "type": "string",
            "description": "Mobile phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "07700 900123"
          },
          "email1Address": {
            "type": "string",
            "description": "First email address held on the main contact details of the constituent.",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "Format the first email address should be sent in.",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "Second email address held on the main contact details of the constituent.",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "Format the second email address should be sent in.",
            "nullable": true,
            "example": "Text"
          },
          "linkedToConstituentId": {
            "type": "string",
            "description": "Constituent the main address is shared with.\r\n<ul><li>Set when the main contact details of the constituent link to another constituent; the\r\naddress properties then come from that constituent while the phone numbers, email\r\naddresses and salutation stay with this one.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9f1c1e8e-0d0e-4c4d-9f6a-2b7c9f3e51aa"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name may be swapped when Donorfy detects they were entered the wrong way round.",
            "nullable": true,
            "example": false
          },
          "isGroup": {
            "type": "boolean",
            "description": "Whether the constituent is a group, such as an organisation or trust, rather than an individual.\r\n<ul><li>Derived from the constituent type.</li></ul>",
            "nullable": true,
            "example": false
          },
          "archiveDate": {
            "type": "string",
            "description": "Date the constituent was archived.\r\n<ul><li>Empty while the constituent is active.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-15T09:30:00Z"
          },
          "archiveReason": {
            "type": "string",
            "description": "Reason the constituent was archived, as described in the `Archive Reasons` lookup.",
            "nullable": true,
            "example": "Deceased"
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the constituent is excluded from Gift Aid claims.",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "Identifier of the constituent in the system that owns the data outside Donorfy.",
            "nullable": true,
            "example": "CRM-00012345"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "Campaign the constituent was recruited by.",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "Identifier of the campaign the constituent was recruited by.",
            "format": "uuid",
            "nullable": true,
            "example": "6f9619ff-8b86-d011-b42d-00cf4fc964ff"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the constituent was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-05T14:22:31Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the constituent was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-02-11T08:05:09Z"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.TagApiResponse"
            },
            "description": "Tags allocated to the constituent, restricted to the tag categories the caller is\r\npermitted to see.\r\n<ul><li>Returned only when an `include` asks for them: the pinned tags with\r\n`include=pinnedTags` when listing constituents, every tag with `include=tags`\r\nwhen retrieving one.</li><li>Empty when the constituent has no tags the caller may see.</li></ul>",
            "nullable": true
          },
          "trackingCodes": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.TrackingCodeApiResponse"
              }
            ],
            "description": "The UTM tracking codes captured when the constituent was created.\r\n<ul><li>Returned only when `include=trackingCodes` is supplied.</li></ul>",
            "nullable": true
          },
          "contactDetails": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.ContactDetailApiResponse"
            },
            "description": "The addresses, phone numbers and email addresses of the constituent.\r\n<ul><li>Returned only when `include=contactDetails` is supplied.</li></ul>",
            "nullable": true
          },
          "channelPreferences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.ChannelPreferenceApiResponse"
            },
            "description": "The channels the constituent may, or may not, be contacted through.\r\n<ul><li>Returned only when `include=channelPreferences` is supplied.</li><li>A null `preferenceAllowed` means the constituent's wishes are not known because\r\nthe preference is unconfirmed, not that contact has been refused.</li></ul>",
            "nullable": true
          },
          "givingSummary": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.GivingSummaryApiResponse"
              }
            ],
            "description": "The giving summary of the constituent.\r\n<ul><li>Returned only when `include=givingSummary` is supplied.</li></ul>",
            "nullable": true
          }
        },
        "description": "A single constituent together with the related resources that were requested with `include`."
      },
      "Constituent.ConstituentListApiInclude": {
        "enum": [
          "pinnedTags"
        ],
        "type": "string",
        "description": "The related resources that can be expanded when listing constituents.\n\nValues: pinnedTags. Send the value, not the integer it stands for. Integers are still accepted for compatibility: pinnedTags = 0."
      },
      "Constituent.ConstituentTagApiSort": {
        "enum": [
          "tagName",
          "tagCategory",
          "isActive",
          "isPinned"
        ],
        "type": "string",
        "description": "The fields a list of constituent tags can be sorted by.\n\nValues: tagName, tagCategory, isActive, isPinned. Send the value, not the integer it stands for. Integers are still accepted for compatibility: tagName = 0, tagCategory = 1, isActive = 2, isPinned = 3."
      },
      "Constituent.ContactDetailApiResponse": {
        "type": "object",
        "properties": {
          "contactDetailsId": {
            "type": "string",
            "description": "Unique identifier of the contact details.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "contactDetailsType": {
            "type": "string",
            "description": "Type of the contact details.",
            "nullable": true,
            "example": "Personal"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether these are the contact details currently in use.",
            "nullable": true,
            "example": true
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the contact details were created.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-15T09:30:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the contact details were last changed.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-03-02T14:05:00Z"
          },
          "jobTitle": {
            "type": "string",
            "description": "Job title of the constituent at this address.",
            "nullable": true,
            "example": "Fundraising Manager"
          },
          "department": {
            "type": "string",
            "description": "Department of the constituent at this address.",
            "nullable": true,
            "example": "Fundraising"
          },
          "salutation": {
            "type": "string",
            "description": "Greeting used when writing to the constituent at this address.",
            "nullable": true,
            "example": "Dear Jane"
          },
          "labelName": {
            "type": "string",
            "description": "Name used on labels and envelopes for this address.",
            "nullable": true,
            "example": "Mrs Jane Smith"
          },
          "organisationName": {
            "type": "string",
            "description": "Name of the organisation at this address.",
            "nullable": true,
            "example": "Acme Charitable Trust"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House name or number of the address.",
            "nullable": true,
            "example": 42
          },
          "addressLine1": {
            "type": "string",
            "description": "First line of the address.",
            "nullable": true,
            "example": "High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "Second line of the address.",
            "nullable": true,
            "example": "Jesmond"
          },
          "town": {
            "type": "string",
            "description": "Town or city of the address.",
            "nullable": true,
            "example": "Newcastle upon Tyne"
          },
          "county": {
            "type": "string",
            "description": "County, state or region of the address.",
            "nullable": true,
            "example": "Tyne and Wear"
          },
          "postalCode": {
            "type": "string",
            "description": "Postcode or zip code of the address.",
            "nullable": true,
            "example": "NE1 4ST"
          },
          "country": {
            "type": "string",
            "description": "Country of the address.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "Main landline phone number.",
            "nullable": true,
            "example": "01234 567890"
          },
          "phone2": {
            "type": "string",
            "description": "Alternative landline phone number.",
            "nullable": true,
            "example": "01234 567891"
          },
          "mobilePhone": {
            "type": "string",
            "description": "Mobile phone number.",
            "nullable": true,
            "example": "07700 900123"
          },
          "email1Address": {
            "type": "string",
            "description": "Main email address.",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "Format the main email address is sent in.",
            "nullable": true,
            "example": "HTML"
          },
          "email1Status": {
            "type": "string",
            "description": "Delivery status of the main email address.",
            "nullable": true,
            "example": "Valid"
          },
          "email2Address": {
            "type": "string",
            "description": "Alternative email address.",
            "nullable": true,
            "example": "j.smith@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "Format the alternative email address is sent in.",
            "nullable": true,
            "example": "Text"
          },
          "email2Status": {
            "type": "string",
            "description": "Delivery status of the alternative email address.",
            "nullable": true,
            "example": "Valid"
          },
          "linkedToConstituentId": {
            "type": "string",
            "description": "Unique identifier of the constituent these contact details take their address from.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        },
        "description": "A set of contact details — an address, phone numbers and email addresses — held for a constituent."
      },
      "Constituent.CreateActivityApiRequest": {
        "required": [
          "constituentId",
          "activityType"
        ],
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "The ID of the constituent the activity is recorded against.\r\n<ul><li>Required.</li><li>Must identify an existing constituent. A constituent is never created or matched.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3f2504e0-4f89-11d3-9a0c-0305e82c3301"
          },
          "activityType": {
            "type": "string",
            "description": "The type of the activity, as the ID or the description of an activity type.\r\n<ul><li>Required.</li><li>Inactive activity types are accepted.</li><li>Its labels say which of the user-defined extra fields may be given a value.</li></ul>",
            "nullable": true,
            "example": "Phone Call"
          },
          "activityDate": {
            "type": "string",
            "description": "The date of the activity, without a time.\r\n<ul><li>Optional. Defaults to today (UTC). A date in the future is accepted.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "campaignId": {
            "type": "string",
            "description": "The ID of the campaign the activity is attributed to.\r\n<ul><li>Optional.</li><li>Must identify an existing campaign, active or not.</li><li>When `campaign` is supplied as well, the two must identify the same campaign.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "6a7a4e0e-9f3a-4c5e-9b23-2f1d5c8a7b40"
          },
          "campaign": {
            "type": "string",
            "description": "The name of the campaign the activity is attributed to. Prefer `campaignId`, as a\r\nname is not unique.\r\n<ul><li>Optional.</li><li>Must match the description of exactly one existing campaign, active or not; an ambiguous name is rejected, so use `campaignId` instead.</li></ul>",
            "nullable": true,
            "example": "Summer Appeal"
          },
          "isConfidential": {
            "type": "boolean",
            "description": "Whether the activity is confidential.\r\n<ul><li>Optional. Defaults to `false`.</li><li>A user needs the `AccessConfidentialActivities` permission to record a confidential activity.</li></ul>",
            "nullable": true,
            "example": false
          },
          "showAlert": {
            "type": "boolean",
            "description": "Whether the activity is shown as an alert on the constituent's record in Donorfy.\r\n<ul><li>Optional. Stored as not set when omitted, which is not shown as an alert.</li></ul>",
            "nullable": true,
            "example": false
          },
          "notes": {
            "type": "string",
            "description": "Notes about the activity.\r\n<ul><li>Optional.</li></ul>",
            "nullable": true,
            "example": "Called to thank them for their donation."
          },
          "code1": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 1 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 1"
          },
          "code2": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 2 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 2"
          },
          "code3": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 3 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 3"
          },
          "code4": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 4 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 4"
          },
          "code5": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 5 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 5"
          },
          "code6": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 6 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 6"
          },
          "code7": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 7 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 7"
          },
          "code8": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 8 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 8"
          },
          "code9": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 9 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 9"
          },
          "code10": {
            "maxLength": 500,
            "type": "string",
            "description": "The value of the user-defined code field 10 of the activity.\r\n<ul><li>Optional. Maximum 500 characters.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "nullable": true,
            "example": "Code value 10"
          },
          "yesNo1": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 1 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo2": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 2 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo3": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 3 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo4": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 4 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo5": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 5 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo6": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 6 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo7": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 7 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo8": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 8 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo9": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 9 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "yesNo10": {
            "type": "boolean",
            "description": "The value of the user-defined yes/no field 10 of the activity.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label; `false` is a value too.</li></ul>",
            "nullable": true,
            "example": true
          },
          "number1": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 1 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number2": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 2 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number3": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 3 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number4": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 4 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number5": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 5 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number6": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 6 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number7": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 7 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number8": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 8 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number9": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 9 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "number10": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the user-defined number field 10 of the activity.\r\n<ul><li>Optional. Greater than -10,000,000, less than 10,000,000 and with no more than 2 decimal places.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "double",
            "example": 12.5
          },
          "date1": {
            "type": "string",
            "description": "The value of the user-defined date field 1 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date2": {
            "type": "string",
            "description": "The value of the user-defined date field 2 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date3": {
            "type": "string",
            "description": "The value of the user-defined date field 3 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date4": {
            "type": "string",
            "description": "The value of the user-defined date field 4 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date5": {
            "type": "string",
            "description": "The value of the user-defined date field 5 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date6": {
            "type": "string",
            "description": "The value of the user-defined date field 6 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date7": {
            "type": "string",
            "description": "The value of the user-defined date field 7 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date8": {
            "type": "string",
            "description": "The value of the user-defined date field 8 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date9": {
            "type": "string",
            "description": "The value of the user-defined date field 9 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "date10": {
            "type": "string",
            "description": "The value of the user-defined date field 10 of the activity, without a time.\r\n<ul><li>Optional.</li><li>Only accepted when the activity type gives the field a label.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "2026-09-30"
          },
          "linkUrl": {
            "maxLength": 1024,
            "type": "string",
            "description": "A web address related to the activity, such as the page of an event or a fundraising page.\r\nIt is shown as a link on the activity in Donorfy.\r\n<ul><li>Optional. Maximum 1024 characters.</li></ul>",
            "nullable": true,
            "example": "https://www.example.org/events/summer-gala"
          },
          "externalReference1": {
            "maxLength": 50,
            "type": "string",
            "description": "External reference 1 of the activity, such as the identifier of the activity in another system.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "EXT-REF-1"
          },
          "externalReference2": {
            "maxLength": 50,
            "type": "string",
            "description": "External reference 2 of the activity, such as the identifier of the activity in another system.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "EXT-REF-2"
          },
          "externalReference3": {
            "maxLength": 50,
            "type": "string",
            "description": "External reference 3 of the activity, such as the identifier of the activity in another system.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "EXT-REF-3"
          },
          "externalReference4": {
            "maxLength": 50,
            "type": "string",
            "description": "External reference 4 of the activity, such as the identifier of the activity in another system.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "EXT-REF-4"
          },
          "externalReference5": {
            "maxLength": 50,
            "type": "string",
            "description": "External reference 5 of the activity, such as the identifier of the activity in another system.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "EXT-REF-5"
          },
          "utmSource": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM source the activity is tracked against, for example the referrer of the visit.\r\n<ul><li>Optional. Maximum 150 characters, after surrounding spaces are removed.</li></ul>",
            "nullable": true,
            "example": "newsletter"
          },
          "utmMedium": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM medium the activity is tracked against, for example the marketing channel used.\r\n<ul><li>Optional. Maximum 150 characters, after surrounding spaces are removed.</li></ul>",
            "nullable": true,
            "example": "email"
          },
          "utmTerm": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM term the activity is tracked against, for example the paid search keyword used.\r\n<ul><li>Optional. Maximum 150 characters, after surrounding spaces are removed.</li></ul>",
            "nullable": true,
            "example": "donate now"
          },
          "utmContent": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM content the activity is tracked against, for example the creative that was clicked.\r\n<ul><li>Optional. Maximum 150 characters, after surrounding spaces are removed.</li></ul>",
            "nullable": true,
            "example": "banner-a"
          },
          "utmCampaign": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM campaign the activity is tracked against. This is free text and is unrelated to\r\n`campaign` and `campaignId`.\r\n<ul><li>Optional. Maximum 150 characters, after surrounding spaces are removed.</li></ul>",
            "nullable": true,
            "example": "summer-appeal-2026"
          }
        },
        "description": "An activity to record against an existing constituent, such as a phone call, a meeting or a\r\nletter."
      },
      "Constituent.CreateConstituentApiRequest": {
        "required": [
          "constituentType"
        ],
        "type": "object",
        "properties": {
          "constituentType": {
            "type": "string",
            "description": "The type of constituent to create.\r\n<ul><li>Required.</li><li>The identifier, or the description, of an active value in the `Constituent Types` lookup. A value that is a GUID is resolved by identifier, anything else by description.</li><li>Types flagged as a group (for example `Organisation`) accept `organisationName`; all other types reject it.</li></ul>",
            "example": "Individual"
          },
          "title": {
            "type": "string",
            "description": "The title of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "The first name of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "description": "The last name of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Smith"
          },
          "middleName": {
            "type": "string",
            "description": "The middle name of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Elizabeth"
          },
          "prefix": {
            "type": "string",
            "description": "The name prefix used when addressing the constituent.\r\n<ul><li>Optional. Maximum 50 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "The letters or honours that follow the name of the constituent.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "The previous name of the constituent.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "The informal or alternative name the constituent is known by.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Janey"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "The date of birth of the constituent.\r\n<ul><li>Optional. Date in ISO 8601 format (yyyy-MM-dd).</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "gender": {
            "type": "string",
            "description": "The gender of the constituent.\r\n<ul><li>Optional; rejected for a group type, where it is supplied in `mainContact` instead.</li><li>The identifier, or the description, of an active value in the `Genders` lookup. A value that is a GUID is resolved by identifier, anything else by description.</li></ul>",
            "nullable": true,
            "example": "Female"
          },
          "organisationName": {
            "type": "string",
            "description": "The name of the organisation, trust or other group.\r\n<ul><li>Only allowed when `constituentType` is a group type; otherwise the request is rejected. The legacy API stored it on an individual as well, so this is a breaking change in v1.</li><li>Maximum 250 characters.</li></ul>",
            "nullable": true,
            "example": "The Access Group"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "The national identification number of the constituent, for example a National Insurance number.\r\n<ul><li>Optional. Maximum 50 characters.</li><li>Stored as it is given. The `AccessNationalIdentity` role is only needed to read it back or to change it later.</li><li>Accepted for a group, where the CRM shows it as the group's registration number.</li></ul>",
            "nullable": true,
            "example": "QQ123456C"
          },
          "jobTitle": {
            "type": "string",
            "description": "The job title of the constituent, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "The department of the constituent, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Development"
          },
          "salutation": {
            "type": "string",
            "description": "The greeting used when addressing the constituent, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Donorfy derives a default from the name when this is not supplied.</li></ul>",
            "nullable": true,
            "example": "Jane"
          },
          "labelName": {
            "type": "string",
            "description": "The name used on labels and letters, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Donorfy derives a default from the name when this is not supplied.</li></ul>",
            "nullable": true,
            "example": "Mrs Jane Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "The house name or number of the address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "12"
          },
          "addressLine1": {
            "type": "string",
            "description": "The first line of the address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Sheep Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "The second line of the address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Stratford-upon-Avon"
          },
          "town": {
            "type": "string",
            "description": "The town of the address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Warwick"
          },
          "county": {
            "type": "string",
            "description": "The county of the address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Warwickshire"
          },
          "postalCode": {
            "type": "string",
            "description": "The postal code of the address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "CV34 6AA"
          },
          "country": {
            "type": "string",
            "description": "The country of the address, stored on the main contact details.\r\n<ul><li>Optional.</li><li>The identifier, or the description, of an active value in the `Countries` lookup. A value that is a GUID is resolved by identifier, anything else by description.</li></ul>",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "The main phone number, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "01926 123456"
          },
          "phone2": {
            "type": "string",
            "description": "The second phone number, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "01926 654321"
          },
          "mobilePhone": {
            "type": "string",
            "description": "The mobile phone number, stored on the main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "07700 900123"
          },
          "email1Address": {
            "type": "string",
            "description": "The main email address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 250 characters.</li></ul>",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "The format the main email address is sent in, stored on the main contact details.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "The second email address, stored on the main contact details.\r\n<ul><li>Optional. Maximum 250 characters.</li></ul>",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "The format the second email address is sent in, stored on the main contact details.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "Text"
          },
          "linkedToConstituentId": {
            "type": "string",
            "description": "The constituent whose address this constituent shares.\r\n<ul><li>Optional.</li><li>When supplied the address of that constituent is used in place of the address properties above.</li><li>Must be an existing constituent.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "6f9619ff-8b86-d011-b42d-00cf4fc964ff"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name may be swapped when Donorfy detects they were entered the wrong way round.\r\n<ul><li>Optional; defaults to `false` when not supplied.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": false
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the constituent must be excluded from Gift Aid claims.\r\n<ul><li>Optional; defaults to `false` when not supplied.</li></ul>",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "The identifier of the constituent in the system that owns the data outside Donorfy.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "CRM-00012345"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "The campaign the constituent was recruited by.\r\n<ul><li>Optional; ignored when `recruitmentCampaignId` is supplied as well.</li><li>The identifier, or the name, of an existing campaign. A value that is a GUID is resolved by identifier, anything else by name.</li><li>Also recorded against the channel preferences created with the constituent.</li></ul>",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "The identifier of the campaign the constituent was recruited by.\r\n<ul><li>Optional; takes precedence over `recruitmentCampaign`, so a constituent read back and posted again keeps the campaign it held.</li><li>Must be an existing campaign.</li><li>Also recorded against the channel preferences created with the constituent.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9fd8f40c-6df1-ec11-b5cf-0003ff444e27"
          },
          "channelPreferences": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ChannelPreferencesApiRequest"
              }
            ],
            "description": "The keep in touch preferences of the constituent, given per channel as `email`,\r\n`phone`, `mail` and `sms`.\r\n<ul><li>Optional; a channel that is left out, like the whole object when it is omitted, is recorded unconfirmed and reads back with a `preferenceAllowed` of `null`.</li><li>The preferences read back from `GET /v1/constituents/{id}?include=channelPreferences`.</li><li>Recorded against this constituent alone; the preferences of a `mainContact` are supplied inside it.</li></ul>",
            "nullable": true
          },
          "mainContact": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.MainContactApiRequest"
              }
            ],
            "description": "The individual to create as the main contact of the group.\r\n<ul><li>Optional; only accepted when `constituentType` is a group type, and rejected otherwise.</li><li>`firstName` and `lastName` are required inside it.</li><li>Two constituents are created: the group, and the individual returned as `mainContact`. Omit it and only the group is created.</li><li>Nothing is copied from the group: the campaign, `noGiftAid`, `externalKey`, the channel preferences and the contact detail properties of the main contact are the ones supplied inside it.</li><li>The main contact is linked to the group, so the CRM shows the address of the group on the work contact details of the main contact.</li></ul>",
            "nullable": true
          }
        },
        "description": "The details used to create a constituent."
      },
      "Constituent.CreatedConstituentApiResponse": {
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "Unique identifier of the constituent.\r\n<ul><li>Assigned by Donorfy when the constituent is created.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the constituent.\r\n<ul><li>Assigned by Donorfy; used as the human readable reference of the constituent.</li></ul>",
            "format": "int64",
            "example": 10432
          },
          "constituentType": {
            "type": "string",
            "description": "Type of the constituent, as described in the `Constituent Types` lookup.",
            "nullable": true,
            "example": "Individual"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the constituent is active.\r\n<ul><li>`false` once the constituent has been archived.</li></ul>",
            "nullable": true,
            "example": true
          },
          "title": {
            "type": "string",
            "description": "Title of the person.",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "First name of the person.",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "description": "Last name of the person.",
            "nullable": true,
            "example": "Smith"
          },
          "middleName": {
            "type": "string",
            "description": "Middle name of the person.",
            "nullable": true,
            "example": "Elizabeth"
          },
          "prefix": {
            "type": "string",
            "description": "Name prefix used when addressing the constituent.",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "Letters or honours that follow the name of the constituent.",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "Previous name of the constituent.",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "Informal or alternative name the constituent is known by.",
            "nullable": true,
            "example": "Janey"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "Date of birth of the constituent.\r\n<ul><li>Only held for constituents that are not a group.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "gender": {
            "type": "string",
            "description": "Gender of the constituent, as described in the `Genders` lookup.",
            "nullable": true,
            "example": "Female"
          },
          "organisationName": {
            "type": "string",
            "description": "Name of the organisation, trust or other group.\r\n<ul><li>Only held for group constituent types.</li></ul>",
            "nullable": true,
            "example": "The Access Group"
          },
          "description": {
            "type": "string",
            "description": "Description Donorfy holds for the constituent, used as its display name across the CRM.\r\n<ul><li>The organisation name for a group, and `{prefix} {lastName}, {title} {firstName}`\r\nfor an individual.</li><li>Maintained by Donorfy from the name properties of the constituent and read only.</li></ul>",
            "nullable": true,
            "example": "Dr Smith, Mrs Jane"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "National identification number of the constituent, for example a National Insurance number.\r\n<ul><li>For an Access Identity user without the `AccessNationalIdentity` role the value is replaced with `Insufficient Permissions`; system integrations authenticating with Basic auth always receive the value.</li><li>For the same reason, the value cannot be used to filter or sort a collection unless the caller holds that role.</li></ul>",
            "nullable": true,
            "example": "QQ123456C"
          },
          "jobTitle": {
            "type": "string",
            "description": "Job title held on the main contact details of the constituent.",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "Department held on the main contact details of the constituent.",
            "nullable": true,
            "example": "Development"
          },
          "salutation": {
            "type": "string",
            "description": "Salutation used when writing to the constituent, from the main contact details.",
            "nullable": true,
            "example": "Dear Jane"
          },
          "labelName": {
            "type": "string",
            "description": "Name used on labels and envelopes, from the main contact details of the constituent.",
            "nullable": true,
            "example": "Mrs Jane Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House name or number of the main address of the constituent.",
            "nullable": true,
            "example": "42"
          },
          "addressLine1": {
            "type": "string",
            "description": "First line of the main address of the constituent.",
            "nullable": true,
            "example": "42 High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "Second line of the main address of the constituent.",
            "nullable": true,
            "example": "Riverside"
          },
          "town": {
            "type": "string",
            "description": "Town or city of the main address of the constituent.",
            "nullable": true,
            "example": "Loughborough"
          },
          "county": {
            "type": "string",
            "description": "County of the main address of the constituent.",
            "nullable": true,
            "example": "Leicestershire"
          },
          "postalCode": {
            "type": "string",
            "description": "Postal code of the main address of the constituent.",
            "nullable": true,
            "example": "LE11 1AA"
          },
          "country": {
            "type": "string",
            "description": "Country of the main address of the constituent, as described in the `Countries` lookup.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "First landline phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "01234 567890"
          },
          "phone2": {
            "type": "string",
            "description": "Second landline phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "01234 567891"
          },
          "mobilePhone": {
            "type": "string",
            "description": "Mobile phone number held on the main contact details of the constituent.",
            "nullable": true,
            "example": "07700 900123"
          },
          "email1Address": {
            "type": "string",
            "description": "First email address held on the main contact details of the constituent.",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "Format the first email address should be sent in.",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "Second email address held on the main contact details of the constituent.",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "Format the second email address should be sent in.",
            "nullable": true,
            "example": "Text"
          },
          "linkedToConstituentId": {
            "type": "string",
            "description": "Constituent the main address is shared with.\r\n<ul><li>Set when the main contact details of the constituent link to another constituent; the\r\naddress properties then come from that constituent while the phone numbers, email\r\naddresses and salutation stay with this one.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9f1c1e8e-0d0e-4c4d-9f6a-2b7c9f3e51aa"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name may be swapped when Donorfy detects they were entered the wrong way round.",
            "nullable": true,
            "example": false
          },
          "isGroup": {
            "type": "boolean",
            "description": "Whether the constituent is a group, such as an organisation or trust, rather than an individual.\r\n<ul><li>Derived from the constituent type.</li></ul>",
            "nullable": true,
            "example": false
          },
          "archiveDate": {
            "type": "string",
            "description": "Date the constituent was archived.\r\n<ul><li>Empty while the constituent is active.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-15T09:30:00Z"
          },
          "archiveReason": {
            "type": "string",
            "description": "Reason the constituent was archived, as described in the `Archive Reasons` lookup.",
            "nullable": true,
            "example": "Deceased"
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the constituent is excluded from Gift Aid claims.",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "Identifier of the constituent in the system that owns the data outside Donorfy.",
            "nullable": true,
            "example": "CRM-00012345"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "Campaign the constituent was recruited by.",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "Identifier of the campaign the constituent was recruited by.",
            "format": "uuid",
            "nullable": true,
            "example": "6f9619ff-8b86-d011-b42d-00cf4fc964ff"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the constituent was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-01-05T14:22:31Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the constituent was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2026-02-11T08:05:09Z"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.TagApiResponse"
            },
            "description": "Tags allocated to the constituent, restricted to the tag categories the caller is\r\npermitted to see.\r\n<ul><li>Returned only when an `include` asks for them: the pinned tags with\r\n`include=pinnedTags` when listing constituents, every tag with `include=tags`\r\nwhen retrieving one.</li><li>Empty when the constituent has no tags the caller may see.</li></ul>",
            "nullable": true
          },
          "trackingCodes": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.TrackingCodeApiResponse"
              }
            ],
            "description": "The UTM tracking codes captured when the constituent was created.\r\n<ul><li>Returned only when `include=trackingCodes` is supplied.</li></ul>",
            "nullable": true
          },
          "contactDetails": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.ContactDetailApiResponse"
            },
            "description": "The addresses, phone numbers and email addresses of the constituent.\r\n<ul><li>Returned only when `include=contactDetails` is supplied.</li></ul>",
            "nullable": true
          },
          "channelPreferences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.ChannelPreferenceApiResponse"
            },
            "description": "The channels the constituent may, or may not, be contacted through.\r\n<ul><li>Returned only when `include=channelPreferences` is supplied.</li><li>A null `preferenceAllowed` means the constituent's wishes are not known because\r\nthe preference is unconfirmed, not that contact has been refused.</li></ul>",
            "nullable": true
          },
          "givingSummary": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.GivingSummaryApiResponse"
              }
            ],
            "description": "The giving summary of the constituent.\r\n<ul><li>Returned only when `include=givingSummary` is supplied.</li></ul>",
            "nullable": true
          },
          "mainContact": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ConstituentApiResponse"
              }
            ],
            "description": "The individual constituent created as the main contact of the group.\r\n<ul><li>Only returned when a group constituent was created with a `mainContact`.</li></ul>",
            "nullable": true
          }
        },
        "description": "A constituent that has just been created, described the same way a read of it describes it,\r\ntogether with the main contact created alongside it."
      },
      "Constituent.DuplicateCheckApiRequest": {
        "required": [
          "lastName",
          "firstName",
          "emailAddress",
          "phoneNumber",
          "mobilePhone",
          "houseBuildingNumber",
          "addressLine1",
          "postalCode"
        ],
        "type": "object",
        "properties": {
          "lastName": {
            "type": "string",
            "description": "Last name of the person, for example `Smith`.",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "description": "First name of the person, for example `Jane`.",
            "nullable": true
          },
          "emailAddress": {
            "type": "string",
            "description": "Email address of the person, for example `jane.smith@example.com`.",
            "nullable": true
          },
          "phoneNumber": {
            "type": "string",
            "description": "Landline phone number of the person, for example `01234 567890`.",
            "nullable": true
          },
          "mobilePhone": {
            "type": "string",
            "description": "Mobile phone number of the person, for example `07700 900123`.",
            "nullable": true
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House name or number of the address, for example `42`.",
            "nullable": true
          },
          "addressLine1": {
            "type": "string",
            "description": "First line of the address, for example `High Street`.",
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "description": "Postcode of the address, for example `NE1 4ST`.",
            "nullable": true
          }
        },
        "description": "The details of a person to look for possible duplicates of."
      },
      "Constituent.DuplicateCheckApiResponse": {
        "required": [
          "constituentId",
          "constituentNumber",
          "lastName",
          "firstName",
          "emailAddress",
          "phoneNumber",
          "mobilePhone",
          "houseBuildingNumber",
          "addressLine1",
          "postalCode",
          "score",
          "matchedRules"
        ],
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "Unique identifier of the existing constituent, for example `3fa85f64-5717-4562-b3fc-2c963f66afa6`.",
            "format": "uuid"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Constituent number of the existing constituent, for example `10023`.",
            "format": "int64"
          },
          "lastName": {
            "type": "string",
            "description": "Last name held for the existing constituent, for example `Smith`.",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "description": "First name held for the existing constituent, for example `Jane`.",
            "nullable": true
          },
          "emailAddress": {
            "type": "string",
            "description": "Primary email address held for the existing constituent, for example `jane.smith@example.com`.",
            "nullable": true
          },
          "phoneNumber": {
            "type": "string",
            "description": "Landline phone number held for the existing constituent, for example `01234 567890`.",
            "nullable": true
          },
          "mobilePhone": {
            "type": "string",
            "description": "Mobile phone number held for the existing constituent, for example `07700 900123`.",
            "nullable": true
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "House name or number held for the existing constituent, for example `42`.",
            "nullable": true
          },
          "addressLine1": {
            "type": "string",
            "description": "First line of the address held for the existing constituent, for example `High Street`.",
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "description": "Postcode held for the existing constituent, for example `NE1 4ST`.",
            "nullable": true
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Confidence score of the highest scoring rule that matched, for example `15`. Results are ordered by this value, highest first.",
            "format": "int32"
          },
          "matchedRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.MatchedRuleApiResponse"
            },
            "description": "Every rule that matched, ordered by score, highest first."
          }
        },
        "description": "An existing constituent that may be a duplicate of the details supplied."
      },
      "Constituent.GivingSummaryApiResponse": {
        "type": "object",
        "properties": {
          "lifetimeGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts across the constituent's lifetime.",
            "format": "double",
            "example": 4825.50
          },
          "lifetimeConnectedGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of the gifts, pledges and soft credits connected to the constituent across\r\ntheir lifetime.",
            "format": "double",
            "example": 7475.50
          },
          "dateOfFirstGift": {
            "type": "string",
            "description": "The date of the constituent's first gift.",
            "format": "date",
            "nullable": true,
            "example": "2019-04-02"
          },
          "dateOfLastGift": {
            "type": "string",
            "description": "The date of the constituent's last gift.",
            "format": "date",
            "nullable": true,
            "example": "2025-08-14"
          },
          "lifetimeGiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts across the constituent's lifetime.",
            "format": "int32",
            "example": 37
          },
          "averageGiftAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The average value of a gift.",
            "format": "double",
            "example": 130.42
          },
          "currentYearGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the current financial year.",
            "format": "double",
            "example": 480.00
          },
          "currentYearMinus1GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the financial year one year before the current one.",
            "format": "double",
            "example": 640.00
          },
          "currentYearMinus2GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the financial year two years before the current one.",
            "format": "double",
            "example": 520.00
          },
          "currentYearGiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the current financial year.",
            "format": "int32",
            "example": 4
          },
          "currentYearMinus1GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the financial year one year before the current one.",
            "format": "int32",
            "example": 6
          },
          "currentYearMinus2GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the financial year two years before the current one.",
            "format": "int32",
            "example": 5
          },
          "lifetimeGiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed across the constituent's lifetime.",
            "format": "double",
            "example": 1206.25
          },
          "currentYearGiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the current financial year.",
            "format": "double",
            "example": 120.00
          },
          "currentYearMinus1GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the financial year one year before the current one.",
            "format": "double",
            "example": 160.00
          },
          "currentYearMinus2GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the financial year two years before the current one.",
            "format": "double",
            "example": 130.00
          },
          "currentTaxYearGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the current tax year.",
            "format": "double",
            "example": 495.00
          },
          "currentTaxYearMinus1GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the previous tax year.",
            "format": "double",
            "example": 610.00
          },
          "currentTaxYearMinus2GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the prior tax year.",
            "format": "double",
            "example": 505.00
          },
          "currentTaxYearMinus1RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the previous tax year.",
            "format": "double",
            "example": 300.00
          },
          "currentTaxYearRecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the current tax year.",
            "format": "double",
            "example": 240.00
          },
          "currentYearRecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the current financial year.",
            "format": "double",
            "example": 240.00
          },
          "currentYearMinus1RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the financial year one year before the current one.",
            "format": "double",
            "example": 300.00
          },
          "currentYearMinus2RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the financial year two years before the current one.",
            "format": "double",
            "example": 300.00
          },
          "months1To12GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the last 12 months.",
            "format": "double",
            "example": 510.00
          },
          "months13To24GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 620.00
          },
          "months25To36GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 530.00
          },
          "lifetimeTotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution across the constituent's lifetime.",
            "format": "double",
            "example": 5320.50
          },
          "lifetimeNonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income across the constituent's lifetime.",
            "format": "double",
            "example": 495.00
          },
          "firstGiftAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the constituent's first gift.",
            "format": "double",
            "example": 25.00
          },
          "lastGiftAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the constituent's last gift.",
            "format": "double",
            "example": 120.00
          },
          "lowestGiftAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the constituent's lowest gift.",
            "format": "double",
            "example": 10.00
          },
          "dateOfLowestGift": {
            "type": "string",
            "description": "The date of the constituent's lowest gift.",
            "format": "date",
            "nullable": true,
            "example": "2020-01-09"
          },
          "highestGiftAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The value of the constituent's highest gift.",
            "format": "double",
            "example": 500.00
          },
          "dateOfHighestGift": {
            "type": "string",
            "description": "The date of the constituent's highest gift.",
            "format": "date",
            "nullable": true,
            "example": "2023-06-30"
          },
          "currentYearTotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the current financial year.",
            "format": "double",
            "example": 535.00
          },
          "currentYearMinus1TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the financial year one year before the current one.",
            "format": "double",
            "example": 700.00
          },
          "currentYearMinus2TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the financial year two years before the current one.",
            "format": "double",
            "example": 565.00
          },
          "currentYearMinus3TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the financial year three years before the current one.",
            "format": "double",
            "example": 455.00
          },
          "currentYearMinus4AndBeforeTotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 3065.50
          },
          "currentYearMinus3GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the financial year three years before the current one.",
            "format": "double",
            "example": 415.00
          },
          "currentYearMinus3GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the financial year three years before the current one.",
            "format": "int32",
            "example": 4
          },
          "currentYearMinus3GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the financial year three years before the current one.",
            "format": "double",
            "example": 103.75
          },
          "currentYearMinus4AndBeforeGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 2770.50
          },
          "currentYearMinus4AndBeforeGiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the fourth financial year before the current one and earlier.",
            "format": "int32",
            "example": 18
          },
          "currentYearMinus4AndBeforeGiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 692.50
          },
          "currentYearMinus1YearToDateTotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the year-to-date period of the previous financial year.",
            "format": "double",
            "example": 400.00
          },
          "currentYearMinus1YearToDateGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the year-to-date period of the previous financial year.",
            "format": "double",
            "example": 360.00
          },
          "currentYearMinus1YearToDateGiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the year-to-date period of the previous financial year.",
            "format": "int32",
            "example": 3
          },
          "currentYearMinus1YearToDateGiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the year-to-date period of the previous financial year.",
            "format": "double",
            "example": 90.00
          },
          "currentConsecutiveGivingYears": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of consecutive years up to and including the current reporting year that the\r\nconstituent has given in, which is zero when they have not given in the current one.",
            "format": "int32",
            "example": 5
          },
          "bestConsecutiveGivingYears": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The highest number of consecutive years the constituent has ever given in.",
            "format": "int32",
            "example": 7
          },
          "donorPyramidLevel": {
            "type": "string",
            "description": "The donor pyramid band the constituent falls into.",
            "nullable": true,
            "example": "B"
          },
          "donorPyramidBandLowerBound": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The lowest giving of the donor pyramid band the constituent falls into. The bound is\r\nexclusive: giving of exactly this amount falls into the band below.",
            "format": "double",
            "example": 1000
          },
          "donorPyramidBandUpperBound": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The highest giving of the donor pyramid band the constituent falls into, which is absent\r\nfor the open ended top band. The bound is inclusive.",
            "format": "double",
            "example": 5000
          },
          "donorPyramidCalculatedOverMonths": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of months of giving the donor pyramid band the constituent falls into is\r\ncalculated over.",
            "format": "int32",
            "example": 36
          },
          "lifetimePledgedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges across the constituent's lifetime.",
            "format": "double",
            "example": 2000.00
          },
          "lifetimePledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges across the constituent's lifetime.",
            "format": "int32",
            "example": 5
          },
          "currentYearPledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the current financial year.",
            "format": "double",
            "example": 500.00
          },
          "currentYearPledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the current financial year.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus1PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the financial year one year before the current one.",
            "format": "double",
            "example": 500.00
          },
          "currentYearMinus1PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the financial year one year before the current one.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus2PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the financial year two years before the current one.",
            "format": "double",
            "example": 500.00
          },
          "currentYearMinus2PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the financial year two years before the current one.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus3PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the financial year three years before the current one.",
            "format": "double",
            "example": 250.00
          },
          "currentYearMinus3PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the financial year three years before the current one.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus4AndBeforePledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 250.00
          },
          "currentYearMinus4AndBeforePledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the fourth financial year before the current one and earlier.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus1YearToDatePledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the year-to-date period of the previous financial year.",
            "format": "double",
            "example": 500.00
          },
          "currentYearMinus1YearToDatePledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the year-to-date period of the previous financial year.",
            "format": "int32",
            "example": 1
          },
          "lifetimeSoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits across the constituent's lifetime.",
            "format": "double",
            "example": 650.00
          },
          "lifetimeSoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits across the constituent's lifetime.",
            "format": "int32",
            "example": 5
          },
          "currentYearSoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the current financial year.",
            "format": "double",
            "example": 150.00
          },
          "currentYearSoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the current financial year.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus1SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the financial year one year before the current one.",
            "format": "double",
            "example": 200.00
          },
          "currentYearMinus1SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the financial year one year before the current one.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus2SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the financial year two years before the current one.",
            "format": "double",
            "example": 150.00
          },
          "currentYearMinus2SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the financial year two years before the current one.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus3SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the financial year three years before the current one.",
            "format": "double",
            "example": 75.00
          },
          "currentYearMinus3SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the financial year three years before the current one.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus4AndBeforeSoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 75.00
          },
          "currentYearMinus4AndBeforeSoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the fourth financial year before the current one and earlier.",
            "format": "int32",
            "example": 1
          },
          "currentYearMinus1YearToDateSoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the year-to-date period of the previous financial year.",
            "format": "double",
            "example": 150.00
          },
          "currentYearMinus1YearToDateSoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the year-to-date period of the previous financial year.",
            "format": "int32",
            "example": 1
          },
          "lifetimeRecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts across the constituent's lifetime.",
            "format": "double",
            "example": 1740.00
          },
          "currentYearMinus3RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the financial year three years before the current one.",
            "format": "double",
            "example": 240.00
          },
          "currentYearMinus4AndBeforeRecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 660.00
          },
          "months1To12TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the last 12 months.",
            "format": "double",
            "example": 565.00
          },
          "months1To12GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the last 12 months.",
            "format": "int32",
            "example": 5
          },
          "months1To12RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the last 12 months.",
            "format": "double",
            "example": 240.00
          },
          "months1To12GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the last 12 months.",
            "format": "double",
            "example": 127.50
          },
          "months13To24TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 680.00
          },
          "months13To24GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the rolling 12-month period 13 to 24 months ago.",
            "format": "int32",
            "example": 6
          },
          "months13To24GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 155.00
          },
          "months13To24RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 300.00
          },
          "months25To36TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 575.00
          },
          "months25To36GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the rolling 12-month period 25 to 36 months ago.",
            "format": "int32",
            "example": 5
          },
          "months25To36GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 132.50
          },
          "months25To36RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 300.00
          },
          "months37To48TotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 470.00
          },
          "months37To48GiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 430.00
          },
          "months37To48GiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts in the rolling 12-month period 37 to 48 months ago.",
            "format": "int32",
            "example": 4
          },
          "months37To48GiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 107.50
          },
          "months37To48RecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 240.00
          },
          "months49AndBeforeTotalContribution": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total contribution 49 months ago and earlier.",
            "format": "double",
            "example": 3030.50
          },
          "months49AndBeforeGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of gifts 49 months ago and earlier.",
            "format": "double",
            "example": 2735.50
          },
          "months49AndBeforeGiftsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of gifts 49 months ago and earlier.",
            "format": "int32",
            "example": 17
          },
          "months49AndBeforeGiftAidReclaimedAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total Gift Aid reclaimed 49 months ago and earlier.",
            "format": "double",
            "example": 683.75
          },
          "months49AndBeforeRecurringGiftsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of recurring gifts 49 months ago and earlier.",
            "format": "double",
            "example": 660.00
          },
          "currentYearNonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the current financial year.",
            "format": "double",
            "example": 55.00
          },
          "currentYearMinus1NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the financial year one year before the current one.",
            "format": "double",
            "example": 60.00
          },
          "currentYearMinus1YearToDateNonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the year-to-date period of the previous financial year.",
            "format": "double",
            "example": 40.00
          },
          "currentYearMinus2NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the financial year two years before the current one.",
            "format": "double",
            "example": 45.00
          },
          "currentYearMinus3NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the financial year three years before the current one.",
            "format": "double",
            "example": 40.00
          },
          "currentYearMinus4AndBeforeNonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the fourth financial year before the current one and earlier.",
            "format": "double",
            "example": 295.00
          },
          "months1To12NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the last 12 months.",
            "format": "double",
            "example": 55.00
          },
          "months13To24NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 60.00
          },
          "months25To36NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 45.00
          },
          "months37To48NonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 40.00
          },
          "months49AndBeforeNonGiftIncome": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total non-gift income 49 months ago and earlier.",
            "format": "double",
            "example": 295.00
          },
          "months1To12PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the last 12 months.",
            "format": "double",
            "example": 500.00
          },
          "months1To12PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the last 12 months.",
            "format": "int32",
            "example": 1
          },
          "months13To24PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 500.00
          },
          "months13To24PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the rolling 12-month period 13 to 24 months ago.",
            "format": "int32",
            "example": 1
          },
          "months25To36PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 500.00
          },
          "months25To36PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the rolling 12-month period 25 to 36 months ago.",
            "format": "int32",
            "example": 1
          },
          "months37To48PledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 250.00
          },
          "months37To48PledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges in the rolling 12-month period 37 to 48 months ago.",
            "format": "int32",
            "example": 1
          },
          "months49AndBeforePledgesAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of pledges 49 months ago and earlier.",
            "format": "double",
            "example": 250.00
          },
          "months49AndBeforePledgesNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of pledges 49 months ago and earlier.",
            "format": "int32",
            "example": 1
          },
          "months1To12SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the last 12 months.",
            "format": "double",
            "example": 150.00
          },
          "months1To12SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the last 12 months.",
            "format": "int32",
            "example": 1
          },
          "months13To24SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the rolling 12-month period 13 to 24 months ago.",
            "format": "double",
            "example": 200.00
          },
          "months13To24SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the rolling 12-month period 13 to 24 months ago.",
            "format": "int32",
            "example": 1
          },
          "months25To36SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the rolling 12-month period 25 to 36 months ago.",
            "format": "double",
            "example": 150.00
          },
          "months25To36SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the rolling 12-month period 25 to 36 months ago.",
            "format": "int32",
            "example": 1
          },
          "months37To48SoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits in the rolling 12-month period 37 to 48 months ago.",
            "format": "double",
            "example": 75.00
          },
          "months37To48SoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits in the rolling 12-month period 37 to 48 months ago.",
            "format": "int32",
            "example": 1
          },
          "months49AndBeforeSoftCreditsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The total value of soft credits 49 months ago and earlier.",
            "format": "double",
            "example": 75.00
          },
          "months49AndBeforeSoftCreditsNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The number of soft credits 49 months ago and earlier.",
            "format": "int32",
            "example": 1
          }
        },
        "description": "The giving summary calculated for a constituent."
      },
      "Constituent.InvalidRequest": {
        "required": [
          "message",
          "errors"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Summary of why the request was rejected."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Constituent.ValidationItem"
            },
            "description": "The individual validation failures of the request; empty when the failure is not specific to a\r\nsingle field."
          }
        },
        "description": "The body returned when a request is rejected because it is not valid."
      },
      "Constituent.MainContactApiRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "The title of the main contact.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "The first name of the main contact.\r\n<ul><li>Required. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "description": "The last name of the main contact.\r\n<ul><li>Required. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Smith"
          },
          "middleName": {
            "type": "string",
            "description": "The middle name of the main contact.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Elizabeth"
          },
          "prefix": {
            "type": "string",
            "description": "The name prefix used when addressing the main contact.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "The letters or honours that follow the name of the main contact.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "The previous name of the main contact.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "The informal or alternative name the main contact is known by.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Janey"
          },
          "gender": {
            "type": "string",
            "description": "The gender of the main contact.\r\n<ul><li>Optional.</li><li>The identifier, or the description, of an active value in the `Genders` lookup. A value that is a GUID is resolved by identifier, anything else by description.</li></ul>",
            "nullable": true,
            "example": "Female"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "The date of birth of the main contact.\r\n<ul><li>Optional. Date in ISO 8601 format (yyyy-MM-dd).</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name of the main contact may be swapped when Donorfy detects they were entered the wrong way round.\r\n<ul><li>Optional; defaults to `false` when not supplied.</li></ul>",
            "nullable": true,
            "example": false
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the main contact must be excluded from Gift Aid claims.\r\n<ul><li>Optional; defaults to `false` when not supplied, whatever the group holds.</li></ul>",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "The identifier of the main contact in the system that owns the data outside Donorfy.\r\n<ul><li>Optional. Maximum 50 characters.</li><li>Held by the main contact alone: the external key of the group is not copied to it.</li></ul>",
            "nullable": true,
            "example": "CRM-00012346"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "The national identification number of the main contact, for example a National Insurance number.\r\n<ul><li>Optional. Maximum 50 characters.</li><li>Stored as it is given. The `AccessNationalIdentity` role is only needed to read it back or to change it later.</li></ul>",
            "nullable": true,
            "example": "QQ123456C"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "The campaign the main contact was recruited by.\r\n<ul><li>Optional; ignored when `recruitmentCampaignId` is supplied as well.</li><li>The identifier, or the name, of an existing campaign. A value that is a GUID is resolved by identifier, anything else by name.</li><li>Held by the main contact alone: the recruitment campaign of the group is not copied to it.</li></ul>",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "The identifier of the campaign the main contact was recruited by.\r\n<ul><li>Optional; takes precedence over `recruitmentCampaign`.</li><li>Must be an existing campaign.</li><li>Also recorded against the channel preferences created with the main contact.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9fd8f40c-6df1-ec11-b5cf-0003ff444e27"
          },
          "jobTitle": {
            "type": "string",
            "description": "The job title of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "The department of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Development"
          },
          "salutation": {
            "type": "string",
            "description": "The greeting used when addressing the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Donorfy derives a default from the name when this is not supplied.</li></ul>",
            "nullable": true,
            "example": "Jane"
          },
          "labelName": {
            "type": "string",
            "description": "The name used on labels and letters for the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Donorfy derives a default from the name when this is not supplied.</li></ul>",
            "nullable": true,
            "example": "Mrs Jane Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "The house name or number of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Left empty when it is not supplied: the address of the group is not copied to the main contact details of the main contact.</li></ul>",
            "nullable": true,
            "example": "12"
          },
          "addressLine1": {
            "type": "string",
            "description": "The first line of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Sheep Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "The second line of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Stratford-upon-Avon"
          },
          "town": {
            "type": "string",
            "description": "The town of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Warwick"
          },
          "county": {
            "type": "string",
            "description": "The county of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "Warwickshire"
          },
          "postalCode": {
            "type": "string",
            "description": "The postal code of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "CV34 6AA"
          },
          "country": {
            "type": "string",
            "description": "The country of the address of the main contact, stored on its main contact details.\r\n<ul><li>Optional.</li><li>The identifier, or the description, of an active value in the `Countries` lookup. A value that is a GUID is resolved by identifier, anything else by description.</li></ul>",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "The main phone number of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "01926 123456"
          },
          "phone2": {
            "type": "string",
            "description": "The second phone number of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "01926 654321"
          },
          "mobilePhone": {
            "type": "string",
            "description": "The mobile phone number of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "07700 900123"
          },
          "email1Address": {
            "type": "string",
            "description": "The main email address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 250 characters.</li></ul>",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "The format the main email address of the main contact is sent in, stored on its main contact details.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "The second email address of the main contact, stored on its main contact details.\r\n<ul><li>Optional. Maximum 250 characters.</li></ul>",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "The format the second email address of the main contact is sent in, stored on its main contact details.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "Text"
          },
          "channelPreferences": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Constituent.ChannelPreferencesApiRequest"
              }
            ],
            "description": "The keep in touch preferences of the main contact, given per channel as `email`,\r\n`phone`, `mail` and `sms`.\r\n<ul><li>Optional; a channel that is left out, like the whole object when it is omitted, is recorded unconfirmed against the main contact and reads back with a `preferenceAllowed` of `null`.</li><li>Held by the main contact alone: the preferences of the group are not copied to it.</li><li>A preference without a campaign is recorded against the recruitment campaign of the main contact, not that of the group.</li></ul>",
            "nullable": true
          }
        },
        "description": "The individual to create as the main contact of a group."
      },
      "Constituent.MatchedRuleApiResponse": {
        "required": [
          "reason",
          "score"
        ],
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "The details that matched, for example `Email, First Name, Last Name`."
          },
          "score": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Confidence score of the rule, between 4 and 15; the higher the score the more likely the constituent is a duplicate.",
            "format": "int32"
          }
        },
        "description": "A duplicate matching rule that matched an existing constituent."
      },
      "Constituent.TagApiResponse": {
        "type": "object",
        "properties": {
          "tagId": {
            "type": "string",
            "description": "Identifier of the tag allocated to the constituent.",
            "format": "uuid",
            "nullable": true,
            "example": "3f2504e0-4f89-11d3-9a0c-0305e82c3301"
          },
          "tagCategory": {
            "type": "string",
            "description": "Category the tag belongs to.",
            "nullable": true,
            "example": "Interests"
          },
          "tagName": {
            "type": "string",
            "description": "Name of the tag.",
            "nullable": true,
            "example": "Golf"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the tag is currently active on the constituent.\r\n<ul><li>`false` once the tag has been removed from the constituent.</li></ul>",
            "nullable": true,
            "example": true
          },
          "isPinned": {
            "type": "boolean",
            "description": "Whether the category of the tag is configured to be pinned, so the tag is shown at the top\r\nof the constituent.\r\n<ul><li>Always `true` for the tags returned with `include=pinnedTags`.</li></ul>",
            "nullable": true,
            "example": true
          }
        },
        "description": "A tag allocated to a constituent."
      },
      "Constituent.TrackingCodeApiResponse": {
        "type": "object",
        "properties": {
          "utmSource": {
            "type": "string",
            "description": "Referrer that sent the constituent, from the `utm_source` parameter.",
            "nullable": true,
            "example": "google"
          },
          "utmMedium": {
            "type": "string",
            "description": "Marketing medium that sent the constituent, from the `utm_medium` parameter.",
            "nullable": true,
            "example": "cpc"
          },
          "utmTerm": {
            "type": "string",
            "description": "Paid search keyword the constituent arrived on, from the `utm_term` parameter.",
            "nullable": true,
            "example": "donate to charity"
          },
          "utmContent": {
            "type": "string",
            "description": "Variant of the advert or link that was used, from the `utm_content` parameter.",
            "nullable": true,
            "example": "banner-a"
          },
          "utmCampaign": {
            "type": "string",
            "description": "Marketing campaign the constituent came from, from the `utm_campaign` parameter.",
            "nullable": true,
            "example": "spring-appeal-2026"
          }
        },
        "description": "The UTM tracking codes captured for a constituent, describing where they came from."
      },
      "Constituent.ValidationItem": {
        "required": [
          "message",
          "field"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Description of what is wrong with the value."
          },
          "field": {
            "type": "string",
            "description": "Name of the field the failure relates to."
          }
        },
        "description": "A single validation failure of a request."
      },
      "IContractResolver": {
        "type": "object"
      },
      "InstanceApiResponse": {
        "type": "object",
        "properties": {
          "applicationSubscriptionId": {
            "type": "string",
            "format": "uuid"
          },
          "organisationId": {
            "type": "string",
            "format": "uuid"
          },
          "tenantCode": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "tenantType": {
            "type": "string",
            "nullable": true
          },
          "isSandbox": {
            "type": "boolean"
          },
          "hasAccess": {
            "type": "boolean",
            "description": "Whether the user can perform the action of the `source` the request named. This is\r\npopulated for every returned instance."
          }
        },
        "description": "A Donorfy instance (tenant) the authenticated user can access for their organisation.\r\nGuid InstanceApiResponse.ApplicationSubscriptionId is the value callers send back as the X-InstanceId\r\nheader, and together with Guid InstanceApiResponse.OrganisationId it identifies the instance in an Evo\r\nworkspace launch URL."
      },
      "InstancesApiResponse": {
        "required": [
          "instances",
          "accessRestricted"
        ],
        "type": "object",
        "properties": {
          "instances": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InstanceApiResponse"
            },
            "description": "The instances of the organisation. By default all instances are returned with their\r\n`hasAccess` value; when `filter=true`, only accessible instances are returned."
          },
          "accessRestricted": {
            "type": "boolean",
            "description": "Whether any instance of the organisation is one the user cannot perform the action of the\r\nsource in, so that an empty list of instances tells a caller the user holds no instance at all\r\nrather than none they can work in."
          }
        },
        "description": "The instances the authenticated user can see for the source the request named, annotated with\r\nwhether the user can perform that source's action."
      },
      "JsonPatchDocumentOfPatchConstituentRequest": {
        "type": "array",
        "items": {
          "required": [
            "op",
            "path"
          ],
          "type": "object",
          "properties": {
            "op": {
              "enum": [
                "add",
                "remove",
                "replace",
                "move",
                "copy",
                "test"
              ],
              "type": "string",
              "description": "The operation to perform.",
              "example": "replace"
            },
            "path": {
              "type": "string",
              "description": "JSON Pointer to the property the operation applies to, for example /lastName.",
              "example": "/lastName"
            },
            "value": {
              "description": "The new value, for the add, replace and test operations."
            },
            "from": {
              "type": "string",
              "description": "JSON Pointer the value is taken from, for the move and copy operations."
            }
          }
        },
        "description": "A JSON Patch document as described by RFC 6902: the list of operations to apply to the resource."
      },
      "Lists.AvailableColumnApiResponse": {
        "required": [
          "fieldName",
          "displayName",
          "fieldType"
        ],
        "type": "object",
        "properties": {
          "fieldName": {
            "type": "string",
            "description": "Name of the column. It is the value used in the `selectedFields` and the `sortBy` of a\r\nlist definition, and the key of the column in the rows of a run."
          },
          "displayName": {
            "type": "string",
            "description": "Name of the column as it is shown to users."
          },
          "fieldType": {
            "type": "string",
            "description": "Kind of value the column holds, for example `String`, `Datetime` or `Currency`."
          }
        },
        "description": "A column a list of this type can output."
      },
      "Lists.AvailableFilterApiResponse": {
        "required": [
          "fieldName",
          "displayName",
          "fieldType",
          "dataType",
          "operators"
        ],
        "type": "object",
        "properties": {
          "fieldName": {
            "type": "string",
            "description": "Name of the field. It is the value used in the `field` of a filter of a list definition."
          },
          "displayName": {
            "type": "string",
            "description": "Name of the field as it is shown to users, and the value used in the `displayName` of a\r\nfilter."
          },
          "fieldType": {
            "type": "string",
            "description": "Kind of value the field holds as it is held against the list type, for example `String`,\r\n`Datetime` or `Tag`. A few of these names, such as `Tag`, are not values of the\r\ndata type enumeration, so send `dataType` rather than this name in a filter."
          },
          "dataType": {
            "type": "string",
            "description": "Value to send in the `dataType` of a filter on this field. It decides which operators can be\r\nused and which operand carries the value, and it is always one of the values of the data type\r\nenumeration."
          },
          "operators": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Comparisons the field can be filtered with; each is a value the `operation` of a filter\r\naccepts."
          }
        },
        "description": "A field a list of this type can be filtered on."
      },
      "Lists.CancelListRunApiResponse": {
        "required": [
          "runId",
          "status",
          "statusCode",
          "message"
        ],
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "description": "Unique identifier of the run that was cancelled.",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "State the run has reached, normally `Cancelling` or `Cancelled`."
          },
          "statusCode": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The state of the run as the numeric code Donorfy holds it under: 7 cancelling and 8 cancelled.",
            "format": "int32"
          },
          "message": {
            "type": "string",
            "description": "Note about the cancellation."
          }
        },
        "description": "The body returned when a run of a list definition has been cancelled."
      },
      "Lists.CreateListDefinitionApiRequest": {
        "required": [
          "listType",
          "listDescription"
        ],
        "type": "object",
        "properties": {
          "listType": {
            "type": "string",
            "description": "Kind of record the list returns.\r\n<ul><li>Required.</li><li>Must be one of the list types returned by `GET v1/lists/types`.</li><li>Cannot be changed once the list has been created.</li></ul>",
            "example": "Constituent"
          },
          "listDescription": {
            "type": "string",
            "description": "Description of the list, as it is shown to users.\r\n<ul><li>Required.</li><li>At most 250 characters.</li></ul>",
            "example": "Active monthly donors"
          }
        },
        "description": "The body of a request creating a list definition."
      },
      "Lists.FilterDefinitionApiResponse": {
        "type": "object",
        "properties": {
          "filterId": {
            "type": "string",
            "description": "Identifier of the filter definition of the list.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "name": {
            "type": "string",
            "description": "Name held against the filter definition; empty for most lists.",
            "nullable": true,
            "example": "Active monthly donors"
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lists.FilterItemApiResponse"
            },
            "description": "Filters that select the rows of the list, in the order they are applied. It holds every filter\r\nof the list, including the system filters Donorfy maintains itself."
          },
          "availableOutputFieldList": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Columns the list can output. Empty when the list has none recorded against it.",
            "example": [
              "FirstName",
              "LastName",
              "EmailAddress"
            ]
          },
          "selectedOutputFieldList": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Columns the list outputs, taken from the `selectedFields` of the list.",
            "example": [
              "FirstName",
              "LastName"
            ]
          },
          "sortBy": {
            "type": "string",
            "description": "Column of the list the rows are ordered by.",
            "nullable": true,
            "example": "LastName"
          },
          "parentListDefnId": {
            "type": "string",
            "description": "Identifier of the list definition the filters belong to.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "commsPreferenceTypeId": {
            "type": "string",
            "description": "Identifier of the communications preference type the communication filters of the list apply\r\nto; an empty identifier when the list has none.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "commsPreferenceType": {
            "type": "string",
            "description": "Description of the communications preference type of the list.",
            "nullable": true,
            "example": "Marketing"
          }
        },
        "description": "The filters and output fields of a list definition, as they are held in the stored list."
      },
      "Lists.FilterItemApiRequest": {
        "required": [
          "filterJoin",
          "nodeJoin",
          "openBracket",
          "closeBracket",
          "field",
          "displayName",
          "dataType",
          "operation",
          "stringOperand",
          "stringOperand2",
          "dateOperand",
          "dateOperand2",
          "decimalOperand",
          "decimalOperand2",
          "integerOperand",
          "integerOperand2",
          "skip",
          "includeNull",
          "system",
          "permission",
          "guidOperand",
          "guidOperand2"
        ],
        "type": "object",
        "properties": {
          "filterItemId": {
            "type": "string",
            "description": "Identifier of the filter.\r\n<ul><li>Send the identifier returned by `GET v1/lists/{listDefinitionId}` to keep an existing\r\nfilter.</li><li>`null` creates a new identifier for the filter.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "filterJoin": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Lists.FilterJoin"
              }
            ],
            "description": "How the filter is joined to the filter before it.\r\n<ul><li>Required; must be one of the values of the enumeration.</li><li>Use `None` for the first filter of the list.</li></ul>"
          },
          "nodeJoin": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Lists.FilterJoin"
              }
            ],
            "description": "Join held against the filter within the group of filters it belongs to. It is stored with the\r\nfilter and returned unchanged.\r\n<ul><li>Required; must be one of the values of the enumeration.</li><li>Send the value returned for an existing filter, or `None` for a new filter.</li></ul>"
          },
          "openBracket": {
            "type": "string",
            "description": "Opening brackets that start a group of filters at this filter.\r\n<ul><li>May only hold `(` characters, one for each group that is opened.</li><li>Every bracket opened must be closed by a later filter.</li><li>`null` or an empty string opens no group.</li></ul>",
            "nullable": true,
            "example": "("
          },
          "closeBracket": {
            "type": "string",
            "description": "Closing brackets that end a group of filters at this filter.\r\n<ul><li>May only hold `)` characters, one for each group that is closed.</li><li>A bracket cannot be closed before it has been opened.</li><li>`null` or an empty string closes no group.</li></ul>",
            "nullable": true,
            "example": ")"
          },
          "field": {
            "type": "string",
            "description": "Field of the list the filter is applied to.\r\n<ul><li>Required for a filter that is not a system filter.</li><li>One of the fields of the list type, as returned by\r\n`GET v1/lists/types/{listTypeName}?include=availableFilters`.</li></ul>",
            "nullable": true,
            "example": "RecurringPaymentStatus"
          },
          "displayName": {
            "type": "string",
            "description": "Name of the field as it is shown to users.\r\n<ul><li>Required for a filter that is not a system filter.</li></ul>",
            "nullable": true,
            "example": "Recurring payment status"
          },
          "dataType": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Lists.ListFieldType"
              }
            ],
            "description": "Kind of value the field holds. It decides which operators can be used and which operand\r\ncarries the value.\r\n<ul><li>Required; must be one of the values of the enumeration.</li></ul>"
          },
          "operation": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Lists.FilterOperator"
              }
            ],
            "description": "Comparison the filter applies to the field.\r\n<ul><li>Required for a filter that is not a system filter; `NoneSpecified` is rejected.</li><li>Must be an operator that applies to the data type of the filter.</li></ul>"
          },
          "stringOperand": {
            "type": "string",
            "description": "Value the field is compared against for text, lookup and multi select fields. For the\r\n`InTheList`, `NotInTheList` and `Has*` operators it holds the values separated\r\nby commas.\r\n<ul><li>`null` is stored as an empty value.</li></ul>",
            "nullable": true,
            "example": "Active"
          },
          "stringOperand2": {
            "type": "string",
            "description": "Second text value, used by the `InRange` and `NotInRange` operators as the end of\r\nthe range.\r\n<ul><li>`null` is stored as an empty value.</li></ul>",
            "nullable": true,
            "example": ""
          },
          "dateOperand": {
            "type": "string",
            "description": "Value the field is compared against for date fields.\r\n<ul><li>`null` when the operator needs no date, for example a relative date operator such as\r\n`ThisMonth`.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-01T00:00:00Z"
          },
          "dateOperand2": {
            "type": "string",
            "description": "Second date, used by the `InRange` and `NotInRange` operators as the end of the\r\nrange.\r\n<ul><li>The range includes both ends, so the date must not be earlier than `dateOperand`.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2025-12-31T00:00:00Z"
          },
          "decimalOperand": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "description": "Value the field is compared against for decimal and currency fields.\r\n<ul><li>Required; send `0` when the operator does not use it.</li></ul>",
            "format": "double",
            "example": 25.5
          },
          "decimalOperand2": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "description": "Second decimal or currency value, used by the `InRange` and `NotInRange` operators\r\nas the end of the range.\r\n<ul><li>Required; send `0` when the operator does not use it.</li><li>The range includes both ends, so the value must not be less than `decimalOperand`.</li></ul>",
            "format": "double",
            "example": 100
          },
          "integerOperand": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Value the field is compared against for whole number fields.\r\n<ul><li>Required; send `0` when the operator does not use it.</li></ul>",
            "format": "int32",
            "example": 1
          },
          "integerOperand2": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Second whole number, used by the `InRange` and `NotInRange` operators as the end of\r\nthe range.\r\n<ul><li>Required; send `0` when the operator does not use it.</li><li>The range includes both ends, so the value must not be less than `integerOperand`.</li></ul>",
            "format": "int32",
            "example": 10
          },
          "skip": {
            "type": "boolean",
            "description": "Flag held against the filter in the stored list definition, marking it as one to be skipped.\r\nIt is stored and returned unchanged.\r\n<ul><li>Required; send `false` for a filter that is to be applied normally.</li></ul>",
            "example": false
          },
          "includeNull": {
            "type": "boolean",
            "description": "Whether rows where the field has no value are treated as matching the filter as well. It is\r\nstored with the filter and returned unchanged.\r\n<ul><li>Required.</li></ul>",
            "example": false
          },
          "system": {
            "type": "boolean",
            "description": "Whether the filter is one Donorfy maintains itself rather than one chosen by a user.\r\n<ul><li>Required.</li><li>`true` stores the filter as it is sent and skips every validation of it, so a system\r\nfilter returned by the API can be sent back unchanged.</li><li>Send `false` for a filter of your own.</li></ul>",
            "example": false
          },
          "permission": {
            "type": "boolean",
            "description": "Flag held against the filter in the stored list definition, marking it as one applied for\r\npermission reasons. It is stored and returned unchanged.\r\n<ul><li>Required; send `false` for a filter of your own.</li></ul>",
            "example": false
          },
          "guidOperand": {
            "type": "string",
            "description": "Value the field is compared against for unique identifier fields.\r\n<ul><li>Required; send an empty identifier when the operator does not use it.</li></ul>",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "guidOperand2": {
            "type": "string",
            "description": "Second unique identifier held against the filter.\r\n<ul><li>Required; send an empty identifier when the operator does not use it.</li></ul>",
            "format": "uuid",
            "example": "00000000-0000-0000-0000-000000000000"
          }
        },
        "description": "A single filter of a list definition, selecting the rows the list returns."
      },
      "Lists.FilterItemApiResponse": {
        "type": "object",
        "properties": {
          "filterItemId": {
            "type": "string",
            "description": "Identifier of the filter.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "filterJoin": {
            "type": "string",
            "description": "How the filter is joined to the filter before it, for example `And`, `Or`,\r\n`Not` or `None`.",
            "nullable": true,
            "example": "And"
          },
          "nodeJoin": {
            "type": "string",
            "description": "Join held against the filter within the group of filters it belongs to, using the same values\r\nas `filterJoin`.",
            "nullable": true,
            "example": "None"
          },
          "openBracket": {
            "type": "string",
            "description": "Opening brackets that start a group of filters at this filter; holds only `(`\r\ncharacters, and is empty when no group is opened.",
            "nullable": true,
            "example": "("
          },
          "closeBracket": {
            "type": "string",
            "description": "Closing brackets that end a group of filters at this filter; holds only `)` characters,\r\nand is empty when no group is closed.",
            "nullable": true,
            "example": ")"
          },
          "field": {
            "type": "string",
            "description": "Field of the list the filter is applied to.",
            "nullable": true,
            "example": "RecurringPaymentStatus"
          },
          "displayName": {
            "type": "string",
            "description": "Name of the field as it is shown to users.",
            "nullable": true,
            "example": "Recurring payment status"
          },
          "dataType": {
            "type": "string",
            "description": "Kind of value the field holds, for example `String`, `Datetime` or `Boolean`.",
            "nullable": true,
            "example": "String"
          },
          "operation": {
            "type": "string",
            "description": "Comparison the filter applies to the field, for example `Equals` or `Contains`.",
            "nullable": true,
            "example": "Equals"
          },
          "stringOperand": {
            "type": "string",
            "description": "Value the field is compared against for text, lookup and multi select fields; the values are\r\nseparated by commas when the operator takes several.",
            "nullable": true,
            "example": "Active"
          },
          "stringOperand2": {
            "type": "string",
            "description": "Second text value, used as the end of the range by the `InRange` and `NotInRange`\r\noperators.",
            "nullable": true,
            "example": ""
          },
          "dateOperand": {
            "type": "string",
            "description": "Value the field is compared against for date fields; `null` when the operator needs no\r\ndate.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-01T00:00:00Z"
          },
          "dateOperand2": {
            "type": "string",
            "description": "Second date, used as the end of the range by the `InRange` and `NotInRange`\r\noperators.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-12-31T00:00:00Z"
          },
          "decimalOperand": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "description": "Value the field is compared against for decimal and currency fields; `0` when the\r\noperator does not use it.",
            "format": "double",
            "example": 25.5
          },
          "decimalOperand2": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "description": "Second decimal or currency value, used as the end of the range by the `InRange` and\r\n`NotInRange` operators.",
            "format": "double",
            "example": 100
          },
          "integerOperand": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Value the field is compared against for whole number fields; `0` when the operator does\r\nnot use it.",
            "format": "int32",
            "example": 1
          },
          "integerOperand2": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Second whole number, used as the end of the range by the `InRange` and `NotInRange`\r\noperators.",
            "format": "int32",
            "example": 10
          },
          "skip": {
            "type": "boolean",
            "description": "Flag held against the filter in the stored list definition, marking it as one to be skipped.",
            "example": false
          },
          "includeNull": {
            "type": "boolean",
            "description": "Whether rows where the field has no value are treated as matching the filter as well.",
            "example": false
          },
          "system": {
            "type": "boolean",
            "description": "Whether the filter is one Donorfy maintains itself rather than one chosen by a user. A system\r\nfilter is stored as it is and is not validated when the list definition is updated.",
            "example": false
          },
          "permission": {
            "type": "boolean",
            "description": "Flag held against the filter in the stored list definition, marking it as one applied for\r\npermission reasons.",
            "example": false
          },
          "guidOperand": {
            "type": "string",
            "description": "Value the field is compared against for unique identifier fields; an empty identifier when the\r\noperator does not use it.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "guidOperand2": {
            "type": "string",
            "description": "Second unique identifier held against the filter; an empty identifier when it is not used.",
            "format": "uuid",
            "example": "00000000-0000-0000-0000-000000000000"
          }
        },
        "description": "A single filter of a list definition, selecting the rows the list returns."
      },
      "Lists.FilterJoin": {
        "enum": [
          "NotAssigned",
          "None",
          "And",
          "Or",
          "Not"
        ],
        "type": "string",
        "description": "How a filter of a list definition is joined to the filters around it.\n\nValues: NotAssigned, None, And, Or, Not. Send the value, not the integer it stands for. Integers are still accepted for compatibility: NotAssigned = 0, None = 1, And = 2, Or = 3, Not = 4."
      },
      "Lists.FilterOperator": {
        "enum": [
          "NoneSpecified",
          "Equals",
          "NotEquals",
          "LessThan",
          "LessThanEqualTo",
          "GreaterThan",
          "GreaterThanEqualTo",
          "InTheList",
          "NotInTheList",
          "StartsWith",
          "DoesNotStartWith",
          "IsEmpty",
          "IsNotEmpty",
          "InRange",
          "NotInRange",
          "IsTrue",
          "IsFalse",
          "HasAll",
          "HasAny",
          "DoesNotHaveAll",
          "DoesNotHaveAny",
          "IsToday",
          "ThisWeek",
          "ThisMonth",
          "NextMonth",
          "LastMonth",
          "ThisYear",
          "LastYear",
          "Next12Months",
          "Last12Months",
          "IsYesterday",
          "IsAfterToday",
          "IsBeforeToday",
          "Custom",
          "Contains",
          "DoesNotContain"
        ],
        "type": "string",
        "description": "The comparison a filter of a list definition applies to the value of its field.\n\nValues: NoneSpecified, Equals, NotEquals, LessThan, LessThanEqualTo, GreaterThan, GreaterThanEqualTo, InTheList, NotInTheList, StartsWith, DoesNotStartWith, IsEmpty, IsNotEmpty, InRange, NotInRange, IsTrue, IsFalse, HasAll, HasAny, DoesNotHaveAll, DoesNotHaveAny, IsToday, ThisWeek, ThisMonth, NextMonth, LastMonth, ThisYear, LastYear, Next12Months, Last12Months, IsYesterday, IsAfterToday, IsBeforeToday, Custom, Contains, DoesNotContain. Send the value, not the integer it stands for. Integers are still accepted for compatibility: NoneSpecified = 0, Equals = 1, NotEquals = 2, LessThan = 3, LessThanEqualTo = 4, GreaterThan = 5, GreaterThanEqualTo = 6, InTheList = 7, NotInTheList = 8, StartsWith = 9, DoesNotStartWith = 10, IsEmpty = 11, IsNotEmpty = 12, InRange = 13, NotInRange = 14, IsTrue = 15, IsFalse = 16, HasAll = 17, HasAny = 18, DoesNotHaveAll = 19, DoesNotHaveAny = 20, IsToday = 21, ThisWeek = 22, ThisMonth = 23, NextMonth = 24, LastMonth = 25, ThisYear = 26, LastYear = 27, Next12Months = 28, Last12Months = 29, IsYesterday = 30, IsAfterToday = 31, IsBeforeToday = 32, Custom = 33, Contains = 34, DoesNotContain = 35."
      },
      "Lists.GenerateListRunApiResponse": {
        "required": [
          "runId",
          "message"
        ],
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "description": "Unique identifier of the run. It is used to follow the progress of the run and to read its rows.",
            "format": "uuid"
          },
          "message": {
            "type": "string",
            "description": "Note about the run, for example that the list was already being generated and the run in progress\r\nwas returned instead of a new one. Empty when the run was started normally.",
            "nullable": true
          }
        },
        "description": "The body returned when a run of a list definition has been accepted for generation."
      },
      "Lists.InvalidRequest": {
        "required": [
          "message",
          "errors"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Summary of why the request was rejected."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lists.ValidationItem"
            },
            "description": "The individual validation failures of the request; empty when the failure is not specific to a\r\nsingle field."
          }
        },
        "description": "The body returned when a request is rejected because it is not valid."
      },
      "Lists.ListDefinitionApiResponse": {
        "type": "object",
        "properties": {
          "listDefinitionId": {
            "type": "string",
            "description": "Unique identifier of the list definition.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "listDescription": {
            "type": "string",
            "description": "Description of the list, as it is shown to users.",
            "nullable": true,
            "example": "Active monthly donors"
          },
          "listType": {
            "type": "string",
            "description": "Kind of record the list returns.",
            "nullable": true,
            "example": "Constituent"
          },
          "rowCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Number of rows the list returned the last time its row count was recorded.",
            "format": "int32",
            "example": 1284
          },
          "rowCountDate": {
            "type": "string",
            "description": "Date and time the row count was recorded, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          }
        },
        "description": "A list definition, as it is returned when list definitions are listed."
      },
      "Lists.ListDefinitionApiSort": {
        "enum": [
          "listType",
          "listDescription",
          "rowCount",
          "rowCountDate"
        ],
        "type": "string",
        "description": "The fields a list of list definitions can be sorted by.\n\nValues: listType, listDescription, rowCount, rowCountDate. Send the value, not the integer it stands for. Integers are still accepted for compatibility: listType = 0, listDescription = 1, rowCount = 2, rowCountDate = 3."
      },
      "Lists.ListDefinitionDetailApiResponse": {
        "type": "object",
        "properties": {
          "listDefinitionId": {
            "type": "string",
            "description": "Unique identifier of the list definition.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "listDescription": {
            "type": "string",
            "description": "Description of the list, as it is shown to users.",
            "nullable": true,
            "example": "Active monthly donors"
          },
          "listType": {
            "type": "string",
            "description": "Kind of record the list returns. It is set when the list is created and cannot be changed.",
            "nullable": true,
            "example": "Constituent"
          },
          "rowCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Number of rows the list returned the last time its row count was recorded.",
            "format": "int32",
            "example": 1284
          },
          "rowCountDate": {
            "type": "string",
            "description": "Date and time the row count was recorded, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          },
          "listVersion": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Version of the list format the definition is held in. It is maintained by Donorfy and cannot\r\nbe changed.",
            "format": "int32",
            "example": 10
          },
          "sortBy": {
            "type": "string",
            "description": "Column of the list the rows are ordered by.",
            "nullable": true,
            "example": "LastName"
          },
          "sortDirection": {
            "type": "string",
            "description": "Direction the rows are ordered in, either `asc` or `desc`.",
            "nullable": true,
            "example": "asc"
          },
          "selectedFields": {
            "type": "string",
            "description": "Columns the list outputs, as a comma separated list of column names.",
            "nullable": true,
            "example": "FirstName,LastName,EmailAddress"
          },
          "includeArchivedConstituents": {
            "type": "string",
            "description": "Whether constituents that have been archived are included in the rows of the list, as\r\n`\"true\"` or `\"false\"`.",
            "nullable": true,
            "example": "false"
          },
          "includeConfidentialActivities": {
            "type": "string",
            "description": "Whether activities marked as confidential are included in the rows of the list, as\r\n`\"true\"` or `\"false\"`.",
            "nullable": true,
            "example": "false"
          },
          "showInMenu": {
            "type": "string",
            "description": "Whether the list is shown in the lists menu of Donorfy, as `\"true\"` or `\"false\"`.",
            "nullable": true,
            "example": "true"
          },
          "whoCanModify": {
            "type": "string",
            "description": "Who is allowed to change the list, as it is held in the stored list definition.",
            "nullable": true,
            "example": "Everyone"
          },
          "listIsLocked": {
            "type": "boolean",
            "description": "Whether the list is locked because it is being edited or generated. A locked list cannot be\r\nupdated or deleted by another user.",
            "nullable": true,
            "example": false
          },
          "listLockedBy": {
            "type": "string",
            "description": "Identifier of the user the list is locked by, when it is locked.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "addedByUserId": {
            "type": "string",
            "description": "Identifier of the user who created the list. Only that user, or an administrator, can delete\r\nit.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "lastRunDate": {
            "type": "string",
            "description": "Date and time the list was last run, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          },
          "listFilterRestriction": {
            "type": "string",
            "description": "Restriction held against the filters of the list in the stored list definition.",
            "nullable": true
          },
          "commsPreferenceTypeId": {
            "type": "string",
            "description": "Identifier of the communications preference type the communication filters of the list apply\r\nto.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "selectedCommsPurposes": {
            "type": "string",
            "description": "Communication purposes the list selects on, as a comma separated list of purpose names.",
            "nullable": true,
            "example": "Fundraising,Events"
          },
          "selectedCommsChannels": {
            "type": "string",
            "description": "Communication channels the list selects on, as a comma separated list of channel names.",
            "nullable": true,
            "example": "Email,Post"
          },
          "filterDefinition": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Lists.FilterDefinitionApiResponse"
              }
            ],
            "description": "Filters and output fields of the list.",
            "nullable": true
          }
        },
        "description": "A list definition, together with its options and the filters it selects rows with."
      },
      "Lists.ListFieldType": {
        "enum": [
          "String",
          "Integer",
          "Decimal",
          "Datetime",
          "Boolean",
          "LookUp",
          "Guid",
          "CommsPurpose",
          "CommsChannel",
          "MultiSelect",
          "Currency"
        ],
        "type": "string",
        "description": "The kind of value a field of a list holds. It decides which operators a filter on the field can\r\nuse and which of the operand properties of the filter carries its value.\n\nValues: String, Integer, Decimal, Datetime, Boolean, LookUp, Guid, CommsPurpose, CommsChannel, MultiSelect, Currency. Send the value, not the integer it stands for. Integers are still accepted for compatibility: String = 0, Integer = 1, Decimal = 2, Datetime = 3, Boolean = 4, LookUp = 5, Guid = 6, CommsPurpose = 7, CommsChannel = 8, MultiSelect = 9, Currency = 10."
      },
      "Lists.ListRunApiResponse": {
        "required": [
          "runId",
          "listId",
          "status",
          "statusCode",
          "message",
          "rowCount",
          "dateAdded",
          "dateChanged"
        ],
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "description": "Unique identifier of the run.",
            "format": "uuid"
          },
          "listId": {
            "type": "string",
            "description": "Identifier of the list definition the run belongs to.",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "State of the run: `NotStarted`, `Ready`, `Preparing`, `Processing`,\r\n`Complete`, `Cancelling`, `Cancelled`, `Error` or `Finalised`. The rows\r\nof the run can be read once it is `Complete`."
          },
          "statusCode": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The state of the run as the numeric code Donorfy holds it under: 0 not started, 2 ready,\r\n3 preparing, 5 processing, 6 complete, 7 cancelling, 8 cancelled, 9 error and 10 finalised.",
            "format": "int32"
          },
          "message": {
            "type": "string",
            "description": "Note about the run, for example why it failed. Empty when there is nothing to report.",
            "nullable": true
          },
          "rowCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Number of rows the run produced. Empty until the run has finished.",
            "format": "int32"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the run was started, in UTC.",
            "format": "date-time"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the state of the run last changed, in UTC.",
            "format": "date-time"
          }
        },
        "description": "A run of a list definition and the state it has reached."
      },
      "Lists.ListRunHistoryApiResponse": {
        "required": [
          "runs"
        ],
        "type": "object",
        "properties": {
          "runs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lists.ListRunHistoryItemApiResponse"
            },
            "description": "The runs of the list definition on the page that was asked for. The page details are returned in\r\nthe `X-Pagination-*` response headers."
          }
        },
        "description": "A page of the runs of a list definition."
      },
      "Lists.ListRunHistoryItemApiResponse": {
        "required": [
          "runId",
          "status",
          "statusCode",
          "rowCount",
          "dateAdded",
          "dateChanged"
        ],
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "description": "Unique identifier of the run.",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "State of the run: `NotStarted`, `Ready`, `Preparing`, `Processing`,\r\n`Complete`, `Cancelling`, `Cancelled`, `Error` or `Finalised`."
          },
          "statusCode": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "The state of the run as the numeric code Donorfy holds it under: 0 not started, 2 ready,\r\n3 preparing, 5 processing, 6 complete, 7 cancelling, 8 cancelled, 9 error and 10 finalised.",
            "format": "int32"
          },
          "rowCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Number of rows the run produced. Empty until the run has finished.",
            "format": "int32"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the run was started, in UTC.",
            "format": "date-time"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the state of the run last changed, in UTC.",
            "format": "date-time"
          }
        },
        "description": "A single run of a list definition, as it is returned in the runs of the list."
      },
      "Lists.ListRunResultsApiResponse": {
        "required": [
          "availableColumns",
          "results"
        ],
        "type": "object",
        "properties": {
          "availableColumns": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Names of the columns the rows hold, in the order the list outputs them. They are also the values\r\n`sortBy` accepts."
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "The rows of the page. Each row is an object keyed by the names in `availableColumns`, and the\r\nvalue of a key is the value of that column for the row, of whichever type the column holds, or\r\n`null` when the row has no value for it."
          }
        },
        "description": "A page of the rows a completed run of a list definition produced."
      },
      "Lists.ListTypeApiInclude": {
        "enum": [
          "availableColumns",
          "availableFilters"
        ],
        "type": "string",
        "description": "The related data that can be expanded in a list type response.\n\nValues: availableColumns, availableFilters. Send the value, not the integer it stands for. Integers are still accepted for compatibility: availableColumns = 0, availableFilters = 1."
      },
      "Lists.ListTypeApiResponse": {
        "required": [
          "name"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the list type. It is the value `POST v1/lists` and the `listType` filter\r\naccept."
          }
        },
        "description": "A kind of record a list definition can return."
      },
      "Lists.ListTypeDetailApiResponse": {
        "required": [
          "name"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the list type."
          },
          "availableColumns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lists.AvailableColumnApiResponse"
            },
            "description": "Columns a list of this type can output. Only returned with `include=availableColumns`.",
            "nullable": true
          },
          "availableFilters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lists.AvailableFilterApiResponse"
            },
            "description": "Fields a list of this type can be filtered on. Only returned with\r\n`include=availableFilters`.",
            "nullable": true
          }
        },
        "description": "A kind of record a list definition can return, with the columns it can output and the fields it\r\ncan be filtered on."
      },
      "Lists.UpdateListDefinitionApiRequest": {
        "required": [
          "listDescription",
          "sortBy",
          "sortDirection",
          "selectedFields",
          "includeArchivedConstituents",
          "includeConfidentialActivities",
          "showInMenu",
          "whoCanModify",
          "commsPreferenceTypeId",
          "selectedCommsPurposes",
          "selectedCommsChannels",
          "listFilterRestriction",
          "filters"
        ],
        "type": "object",
        "properties": {
          "listDescription": {
            "type": "string",
            "description": "Description of the list, as it is shown to users.\r\n<ul><li>Must be supplied and cannot be blank.</li></ul>",
            "nullable": true,
            "example": "Active monthly donors"
          },
          "sortBy": {
            "type": "string",
            "description": "Column of the list the rows are ordered by.\r\n<ul><li>One of the columns of the list type, as returned by\r\n`GET v1/lists/types/{listTypeName}?include=availableColumns`.</li><li>`null` leaves the rows in the order the list produces them.</li></ul>",
            "nullable": true,
            "example": "LastName"
          },
          "sortDirection": {
            "type": "string",
            "description": "Direction the rows are ordered in.\r\n<ul><li>Either `asc` or `desc`, in any case.</li><li>`null` leaves the direction unset.</li></ul>",
            "nullable": true,
            "example": "asc"
          },
          "selectedFields": {
            "type": "string",
            "description": "Columns the list outputs, as a comma separated list of column names.\r\n<ul><li>Each name must be one of the columns of the list type.</li><li>`null` clears the selected columns.</li></ul>",
            "nullable": true,
            "example": "FirstName,LastName,EmailAddress"
          },
          "includeArchivedConstituents": {
            "type": "string",
            "description": "Whether constituents that have been archived are included in the rows of the list.\r\n<ul><li>`\"true\"` or `\"false\"`; `null` leaves the setting unset.</li></ul>",
            "nullable": true,
            "example": "false"
          },
          "includeConfidentialActivities": {
            "type": "string",
            "description": "Whether activities marked as confidential are included in the rows of the list.\r\n<ul><li>`\"true\"` or `\"false\"`; `null` leaves the setting unset.</li></ul>",
            "nullable": true,
            "example": "false"
          },
          "showInMenu": {
            "type": "string",
            "description": "Whether the list is shown in the lists menu of Donorfy.\r\n<ul><li>`\"true\"` or `\"false\"`; `null` leaves the setting unset.</li></ul>",
            "nullable": true,
            "example": "true"
          },
          "whoCanModify": {
            "type": "string",
            "description": "Who is allowed to change the list, as it is held in the stored list definition. The value is\r\nkept as it is sent.\r\n<ul><li>`null` leaves the setting unset.</li></ul>",
            "nullable": true,
            "example": "Everyone"
          },
          "commsPreferenceTypeId": {
            "type": "string",
            "description": "Identifier of the communications preference type the communication filters of the list apply\r\nto.\r\n<ul><li>A lookup of the communications preference types.</li><li>`null` clears the communications preference type, so the current value has to be sent\r\nagain to keep it.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "selectedCommsPurposes": {
            "type": "string",
            "description": "Communication purposes the list selects on, as a comma separated list of purpose names.\r\n<ul><li>`null` clears the selected purposes.</li></ul>",
            "nullable": true,
            "example": "Fundraising,Events"
          },
          "selectedCommsChannels": {
            "type": "string",
            "description": "Communication channels the list selects on, as a comma separated list of channel names.\r\n<ul><li>`null` clears the selected channels.</li></ul>",
            "nullable": true,
            "example": "Email,Post"
          },
          "listFilterRestriction": {
            "type": "string",
            "description": "Restriction held against the filters of the list in the stored list definition. The value is\r\nkept as it is sent.\r\n<ul><li>`null` leaves the setting unset.</li></ul>",
            "nullable": true
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lists.FilterItemApiRequest"
            },
            "description": "Filters that select the rows of the list, in the order they are applied.\r\n<ul><li>Required; send an empty array to remove every filter of the list.</li><li>The filters supplied replace the filters of the list, so the filters that are to be kept\r\nmust be sent again.</li></ul>"
          }
        },
        "description": "The body of a request updating a list definition and the filters it selects rows with."
      },
      "Lists.ValidationItem": {
        "required": [
          "message",
          "field"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Description of what is wrong with the value."
          },
          "field": {
            "type": "string",
            "description": "Name of the field the failure relates to."
          }
        },
        "description": "A single validation failure of a request."
      },
      "Lookups.AdditionalInfoApiResponse": {
        "required": [
          "key",
          "value"
        ],
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Name the value is held against.",
            "example": "code"
          },
          "value": {
            "type": "string",
            "description": "The value held against the name.",
            "example": "DM"
          }
        },
        "description": "One of the extra values held against a lookup."
      },
      "Lookups.InvalidRequest": {
        "required": [
          "message",
          "errors"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Summary of why the request was rejected."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lookups.ValidationItem"
            },
            "description": "The individual validation failures of the request; empty when the failure is not specific to a\r\nsingle field."
          }
        },
        "description": "The body returned when a request is rejected because it is not valid."
      },
      "Lookups.LookupApiResponse": {
        "type": "object",
        "properties": {
          "lookupId": {
            "type": "string",
            "description": "Unique identifier of the lookup.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the lookup can still be chosen.\r\n<ul><li>`false` once the value has been retired.</li></ul>",
            "nullable": true,
            "example": true
          },
          "lookupTypeId": {
            "type": "string",
            "description": "Identifier of the lookup type the lookup belongs to.",
            "format": "uuid",
            "example": "9c1f1f5e-4a1b-4f4c-9c0e-2f9a1b3c4d5e"
          },
          "lookupDescription": {
            "type": "string",
            "description": "Description of the lookup, as it is shown to users.",
            "nullable": true,
            "example": "Direct Mail"
          },
          "lookupTypeDescription": {
            "type": "string",
            "description": "Description of the lookup type the lookup belongs to.",
            "nullable": true,
            "example": "Channels"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the lookup was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T09:30:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the lookup was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          },
          "additionalInfo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lookups.AdditionalInfoApiResponse"
            },
            "description": "The extra values held against the lookup.\r\n<ul><li>Omitted from the response when the lookup holds no extra values.</li></ul>",
            "nullable": true,
            "example": [
              {
                "key": "code",
                "value": "DM"
              },
              {
                "key": "glCode",
                "value": "4001"
              }
            ]
          }
        },
        "description": "A lookup — one of the reference data values belonging to a lookup type, such as a single\r\nchannel or fund."
      },
      "Lookups.LookupApiSort": {
        "enum": [
          "lookupDescription",
          "dateAdded",
          "dateChanged"
        ],
        "type": "string",
        "description": "The fields a list of lookups can be sorted by.\n\nValues: lookupDescription, dateAdded, dateChanged. Send the value, not the integer it stands for. Integers are still accepted for compatibility: lookupDescription = 0, dateAdded = 1, dateChanged = 2."
      },
      "Lookups.LookupTypeApiResponse": {
        "type": "object",
        "properties": {
          "lookupTypeId": {
            "type": "string",
            "description": "Unique identifier of the lookup type.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the lookup type is in use.",
            "nullable": true,
            "example": true
          },
          "isSystem": {
            "type": "boolean",
            "description": "Whether the lookup type is a system lookup type of Donorfy rather than one you added.",
            "nullable": true,
            "example": false
          },
          "lookupTypeName": {
            "type": "string",
            "description": "Name of the lookup type, as it is referenced by the rest of the API.",
            "nullable": true,
            "example": "Channel"
          },
          "language": {
            "type": "string",
            "description": "Language code of this lookup type variant, for example EN.",
            "nullable": true,
            "example": "EN"
          },
          "lookupTypeDescription": {
            "type": "string",
            "description": "Description of the lookup type, as it is shown to users.",
            "nullable": true,
            "example": "Channels"
          },
          "storeDescription": {
            "type": "boolean",
            "description": "Whether the description of the chosen lookup is stored on the records that reference it.\r\n<ul><li>`false` unless it has been set for the lookup type.</li></ul>",
            "nullable": true,
            "example": false
          },
          "allowBlank": {
            "type": "boolean",
            "description": "Whether a record referencing this lookup type may leave the value blank.\r\n<ul><li>`true` unless it has been set for the lookup type.</li></ul>",
            "nullable": true,
            "example": true
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the lookup type was created, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T09:30:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the lookup type was last changed, in UTC.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-03-02T14:05:00Z"
          }
        },
        "description": "A lookup type — a category of configurable reference data, for example payment\r\nmethods or activity types, that the individual lookups belong to."
      },
      "Lookups.LookupTypeApiSort": {
        "enum": [
          "lookupTypeName",
          "dateAdded",
          "dateChanged"
        ],
        "type": "string",
        "description": "The fields a list of lookup types can be sorted by.\n\nValues: lookupTypeName, dateAdded, dateChanged. Send the value, not the integer it stands for. Integers are still accepted for compatibility: lookupTypeName = 0, dateAdded = 1, dateChanged = 2."
      },
      "Lookups.ValidationItem": {
        "required": [
          "message",
          "field"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Description of what is wrong with the value."
          },
          "field": {
            "type": "string",
            "description": "Name of the field the failure relates to."
          }
        },
        "description": "A single validation failure of a request."
      },
      "Object": { },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "format": "int32"
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "Transactions.AllocationApiRequest": {
        "required": [
          "amount"
        ],
        "type": "object",
        "properties": {
          "product": {
            "type": "string",
            "description": "What the amount was given for.\r\n<ul><li>Required unless the campaign has a default product. Must match the description of an active value in the `Products` lookup.</li><li>Defaults to the default product of the campaign.</li></ul>",
            "nullable": true,
            "example": "Donation"
          },
          "quantity": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The number of items the amount covers, recorded alongside the amount.\r\n<ul><li>Optional. Defaults to 1.</li><li>Must be greater than 0. It never multiplies `amount`: the amount allocated is always exactly the amount given.</li></ul>",
            "format": "double",
            "example": 1
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The amount allocated.\r\n<ul><li>Required. The allocation amounts must add up to `amount` of the transaction.</li></ul>",
            "format": "double",
            "example": 60.00
          },
          "fund": {
            "type": "string",
            "description": "The fund the amount is allocated to.\r\n<ul><li>Required unless the campaign has a default fund. Must match the description of an active value in the `Funds` lookup.</li><li>Defaults to the default fund of the campaign.</li></ul>",
            "nullable": true,
            "example": "General"
          },
          "department": {
            "type": "string",
            "description": "The department the amount is allocated to.\r\n<ul><li>Optional. Must match the description of an active value in the `Departments` lookup.</li></ul>",
            "nullable": true,
            "example": "Fundraising"
          },
          "canRecoverTax": {
            "type": "boolean",
            "description": "Whether tax can be recovered on the allocation, for example through Gift Aid.\r\n<ul><li>Optional. Defaults to `true`.</li></ul>",
            "nullable": true,
            "example": true
          },
          "comments": {
            "type": "string",
            "description": "Your notes about the allocation.\r\n<ul><li>Optional.</li></ul>",
            "nullable": true,
            "example": "Raffle ticket"
          },
          "beneficiaryConstituentId": {
            "type": "string",
            "description": "The ID of the constituent that benefits from the allocation.\r\n<ul><li>Optional. Must be an existing constituent.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3f9c0f0e-4a86-4e0f-b2a9-5c1a3a5b1e2d"
          },
          "accountingDate": {
            "type": "string",
            "description": "The date the allocation is recognised (its accounting date).\r\n<ul><li>Optional. Defaults to `datePaid`.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-04"
          },
          "dateDue": {
            "type": "string",
            "description": "The date the allocation is due.\r\n<ul><li>Optional. Defaults to `datePaid`.</li><li>Each allocation may have its own due date.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-04"
          }
        },
        "description": "A part of a payment allocated to a product and fund."
      },
      "Transactions.ChannelPermissionApiRequest": {
        "type": "object",
        "properties": {
          "preferenceAllowed": {
            "type": "boolean",
            "description": "Whether the constituent may be contacted through the channel.\r\n<ul><li>Optional; a channel left out, like the whole object when it is omitted, is recorded unconfirmed and reads back as `null`.</li><li>Supplying `true` or `false` confirms the preference, so it reads back as given.</li></ul>",
            "nullable": true,
            "example": true
          },
          "campaignId": {
            "type": "string",
            "description": "The identifier of the campaign the preference is attributed to.\r\n<ul><li>Optional; defaults to the recruitment campaign of the constituent when the preference is confirmed by `preferenceAllowed`, and is not recorded at all when it is not.</li><li>Takes precedence over `campaign`.</li><li>Must be an existing campaign.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9fd8f40c-6df1-ec11-b5cf-0003ff444e27"
          },
          "campaign": {
            "type": "string",
            "description": "The name of the campaign the preference is attributed to.\r\n<ul><li>Optional; accepted when creating the constituent only, and never returned. The preference reads back with `campaignId`.</li><li>The identifier, or the name, of an existing campaign. A value that is a GUID is resolved by identifier, anything else by name.</li><li>Ignored when `campaignId` is supplied as well.</li></ul>",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "dateAdded": {
            "type": "string",
            "description": "When the preference was given, for loading preferences recorded before today.\r\n<ul><li>Optional; defaults to the moment the constituent is created.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2024-03-12T09:30:00Z"
          }
        },
        "description": "The keep in touch preference recorded for one communication channel."
      },
      "Transactions.ChannelPreferencesApiRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for email.",
            "nullable": true
          },
          "phone": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for phone.",
            "nullable": true
          },
          "mail": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for post.",
            "nullable": true
          },
          "sms": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.ChannelPermissionApiRequest"
              }
            ],
            "description": "The preference for SMS.",
            "nullable": true
          }
        },
        "description": "The communication channels the constituent may be contacted on."
      },
      "Transactions.CreatedTransactionApiResponse": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string",
            "description": "Unique identifier of the payment.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "transactionNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the payment.",
            "format": "int64",
            "example": 10432
          },
          "constituentId": {
            "type": "string",
            "description": "Constituent that made the payment.\r\n<ul><li>Empty for an anonymous payment.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the constituent that made the payment.",
            "format": "int64",
            "example": 10432
          },
          "constituentDescription": {
            "type": "string",
            "description": "Name of the constituent that made the payment.\r\n<ul><li>`Anonymous` when the payment has no constituent.</li></ul>",
            "nullable": true,
            "example": "Jane Smith"
          },
          "isAnonymousTransaction": {
            "type": "boolean",
            "description": "Whether the payment was made anonymously.",
            "example": false
          },
          "connectedConstituentId": {
            "type": "string",
            "description": "Constituent the payment was connected to, when one was supplied.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "connectedConstituentDescription": {
            "type": "string",
            "description": "Name of the constituent the payment was connected to.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "fundraisingPageId": {
            "type": "string",
            "description": "Fundraising page the payment was attributed to, when one was supplied.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Amount of the payment.",
            "format": "double",
            "example": 25.00
          },
          "currency": {
            "type": "string",
            "description": "Currency of the payment.",
            "nullable": true,
            "example": "GBP"
          },
          "currencyId": {
            "type": "string",
            "description": "Unique identifier of the currency.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "paymentMethod": {
            "type": "string",
            "description": "Method the payment was made by.",
            "nullable": true,
            "example": "Direct Debit"
          },
          "paymentMethodId": {
            "type": "string",
            "description": "Unique identifier of the payment method.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaign": {
            "type": "string",
            "description": "Campaign the payment is attributed to.",
            "nullable": true,
            "example": "Winter Appeal"
          },
          "campaignId": {
            "type": "string",
            "description": "Unique identifier of the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "channel": {
            "type": "string",
            "description": "Channel the payment came through.",
            "nullable": true,
            "example": "Online"
          },
          "channelId": {
            "type": "string",
            "description": "Unique identifier of the channel.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "acknowledgement": {
            "type": "string",
            "description": "Acknowledgement sent for the payment.",
            "nullable": true,
            "example": "Thank you letter"
          },
          "acknowledgementId": {
            "type": "string",
            "description": "Unique identifier of the acknowledgement.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "bankAccount": {
            "type": "string",
            "description": "Bank account the payment was paid into.",
            "nullable": true,
            "example": "Main Current Account"
          },
          "bankAccountId": {
            "type": "string",
            "description": "Unique identifier of the bank account.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "acknowledgementText": {
            "type": "string",
            "description": "Text recorded with the acknowledgement of the payment.",
            "nullable": true,
            "example": "Sent 2025-01-20"
          },
          "reference": {
            "type": "string",
            "description": "Reference recorded against the payment.",
            "nullable": true,
            "example": "CHQ-1042"
          },
          "payoutReference": {
            "type": "string",
            "description": "Reference of the payout the payment was settled in.",
            "nullable": true,
            "example": "PO-2025-01-31"
          },
          "comments": {
            "type": "string",
            "description": "Comments recorded against the payment.",
            "nullable": true,
            "example": "Given at the winter event"
          },
          "enteredByUser": {
            "type": "string",
            "description": "User that entered the payment.",
            "nullable": true,
            "example": "jane.smith@example.org"
          },
          "transactionStatus": {
            "type": "string",
            "description": "Status of the payment.",
            "nullable": true,
            "example": "Paid"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the payment is active.",
            "nullable": true,
            "example": true
          },
          "datePaid": {
            "type": "string",
            "description": "Date the payment was paid.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15"
          },
          "dateTimePaid": {
            "type": "string",
            "description": "Date and time the payment was paid.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T10:32:00Z"
          },
          "acknowledgedOn": {
            "type": "string",
            "description": "Date the payment was acknowledged on.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-20"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the payment was added.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T10:32:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the payment was last changed.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-16T09:04:00Z"
          },
          "processingCostsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Costs deducted from the payment by the processor.",
            "format": "double",
            "example": 0.54
          },
          "giftAidStatus": {
            "type": "string",
            "description": "Gift Aid status of the payment.",
            "nullable": true,
            "example": "Claimed"
          },
          "giftAidStatusDetails": {
            "type": "string",
            "description": "Detail recorded alongside the Gift Aid status of the payment, such as why it cannot be\r\nclaimed.",
            "nullable": true,
            "example": "No declaration held"
          },
          "giftAidAmountClaimed": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Gift Aid claimed on the payment.",
            "format": "double",
            "example": 6.25
          },
          "isRecurringGift": {
            "type": "boolean",
            "description": "Whether the payment is flagged as a recurring gift.",
            "example": false
          },
          "isRecurringPayment": {
            "type": "boolean",
            "description": "Whether the payment was collected by a recurring payment instruction.",
            "example": true
          },
          "recurringPaymentInstructionId": {
            "type": "string",
            "description": "Recurring payment instruction that collected the payment.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "allocations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.TransactionAllocationApiResponse"
            },
            "description": "Allocations splitting the payment across products and funds.\r\n<ul><li>Always returned when a single payment is retrieved.</li><li>When payments are listed, only returned when asked for with\r\n`include=allocations`.</li></ul>",
            "nullable": true
          },
          "trackingCodes": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TrackingCodeApiResponse"
              }
            ],
            "description": "The UTM tracking codes captured for the payment.\r\n<ul><li>Returned only when `include=trackingCodes` is supplied.</li><li>Omitted when neither the payment nor the constituent that paid carries any.</li></ul>",
            "nullable": true
          },
          "softCredits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.SoftCreditApiResponse"
            },
            "description": "The constituents soft credited with the payment.\r\n<ul><li>Returned only when `include=softCredits` is supplied.</li></ul>",
            "nullable": true
          }
        },
        "description": "A payment that has just been created, described the same way a read of it describes it."
      },
      "Transactions.CreateTransactionApiRequest": {
        "required": [
          "datePaid",
          "amount",
          "allocations"
        ],
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "The ID of the constituent the transaction belongs to.\r\n<ul><li>Required unless `newConstituent` or `isAnonymousTransaction` is used.</li><li>Must be an existing constituent.</li><li>An all-zeros ID counts as not supplied.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "8ba1a9fa-2b52-4f5e-9d64-4a2d0a1c1f9b"
          },
          "connectedConstituentId": {
            "type": "string",
            "description": "The ID of the constituent the transaction is connected to.\r\n<ul><li>Optional. Must be an existing constituent.</li><li>An all-zeros ID counts as not supplied.</li><li>Records a connection to another constituent, for example the employer that matched the gift.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3f2b6d18-9c47-4b1e-8f0a-6b7c2d5e4a31"
          },
          "isAnonymousTransaction": {
            "type": "boolean",
            "description": "Whether the transaction has no donor.\r\n<ul><li>Optional; defaults to `false`.</li><li>Cannot be combined with `constituentId` or `newConstituent`.</li><li>The allocation `beneficiaryConstituentId` may still be used.</li></ul>",
            "example": false
          },
          "newConstituent": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.NewConstituentApiRequest"
              }
            ],
            "description": "The constituent to create and attach the transaction to.\r\n<ul><li>Optional; cannot be combined with `constituentId` or `isAnonymousTransaction`.</li><li>The constituent is only created once the rest of the request has been found valid.</li></ul>",
            "nullable": true
          },
          "datePaid": {
            "type": "string",
            "description": "The date the payment was made.\r\n<ul><li>Required.</li></ul>",
            "format": "date-time",
            "nullable": true,
            "example": "2026-08-04"
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The amount of the payment.\r\n<ul><li>Required.</li><li>Must equal the sum of the allocation amounts.</li></ul>",
            "format": "double",
            "example": 100.00
          },
          "fundraisingPageId": {
            "type": "string",
            "description": "The fundraising page the transaction is attributed to.\r\n<ul><li>Optional. Must identify an existing fundraising page.</li><li>An all-zeros ID counts as not supplied.</li><li>When supplied, page defaults are used for values omitted from this request.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "8ba1a9fa-2b52-4f5e-9d64-4a2d0a1c1f9b"
          },
          "campaignId": {
            "type": "string",
            "description": "The ID of the campaign the transaction is attributed to.\r\n<ul><li>Required, unless `campaign` or a fundraising page supplies the campaign.</li><li>Must identify an existing campaign that the user is allowed to use.</li><li>When `campaign` is supplied as well, the two must identify the same campaign.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "6a7a4e0e-9f3a-4c5e-9b23-2f1d5c8a7b40"
          },
          "campaign": {
            "type": "string",
            "description": "The name of the campaign the transaction is attributed to. Prefer `campaignId`, as a\r\nname is not unique.\r\n<ul><li>Required, unless `campaignId` or a fundraising page supplies the campaign.</li><li>Must match the description of exactly one existing campaign, active or not; an ambiguous name is rejected, so use `campaignId` instead.</li><li>The default product and fund of the campaign are used for allocations that do not name their own.</li></ul>",
            "nullable": true,
            "example": "Summer Appeal"
          },
          "paymentMethod": {
            "type": "string",
            "description": "How the payment was made.\r\n<ul><li>Required, unless the fundraising page supplies it.</li><li>Must match the description of an active value in the `Payment Methods` lookup.</li></ul>",
            "nullable": true,
            "example": "Credit Card"
          },
          "bankAccount": {
            "type": "string",
            "description": "The bank account the payment was paid into.\r\n<ul><li>Optional. Must match the description of an active value in the `Bank Accounts` lookup.</li></ul>",
            "nullable": true,
            "example": "Main"
          },
          "currency": {
            "type": "string",
            "description": "The currency of the payment.\r\n<ul><li>Optional. Must match the description of an active value in the `Currencies` lookup.</li><li>Defaults to your home currency; the request is rejected when neither is set.</li></ul>",
            "nullable": true,
            "example": "GBP"
          },
          "channel": {
            "type": "string",
            "description": "The channel the payment came through.\r\n<ul><li>Optional. Must match the description of an active value in the `Channels` lookup.</li></ul>",
            "nullable": true,
            "example": "Web"
          },
          "acknowledgement": {
            "type": "string",
            "description": "How the payment is acknowledged.\r\n<ul><li>Optional. Must match the description of an active value in the `Acknowledgements` lookup.</li></ul>",
            "nullable": true,
            "example": "Standard"
          },
          "acknowledgementText": {
            "type": "string",
            "description": "The text used when the payment is acknowledged.\r\n<ul><li>Optional.</li></ul>",
            "nullable": true,
            "example": "Thank you for your gift."
          },
          "reference": {
            "maxLength": 120,
            "type": "string",
            "description": "Your reference for the payment.\r\n<ul><li>Optional. Maximum 120 characters.</li></ul>",
            "nullable": true,
            "example": "Cheque 1234"
          },
          "payoutReference": {
            "maxLength": 100,
            "type": "string",
            "description": "The reference of the payout the payment was settled in.\r\n<ul><li>Optional. Maximum 100 characters.</li></ul>",
            "nullable": true,
            "example": "PO-2026-08-04"
          },
          "processingCostsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The costs of processing the payment, for example card fees.\r\n<ul><li>Optional. Defaults to 0.</li></ul>",
            "format": "double",
            "example": 1.50
          },
          "utmSource": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM source the transaction is tracked against, for example the referrer of the visit.\r\n<ul><li>Optional. Maximum 150 characters.</li></ul>",
            "nullable": true,
            "example": "newsletter"
          },
          "utmMedium": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM medium the transaction is tracked against, for example the marketing channel used.\r\n<ul><li>Optional. Maximum 150 characters.</li></ul>",
            "nullable": true,
            "example": "email"
          },
          "utmTerm": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM term the transaction is tracked against, for example the paid search keyword used.\r\n<ul><li>Optional. Maximum 150 characters.</li></ul>",
            "nullable": true,
            "example": "donate now"
          },
          "utmContent": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM content the transaction is tracked against, for example the creative that was clicked.\r\n<ul><li>Optional. Maximum 150 characters.</li></ul>",
            "nullable": true,
            "example": "footer-link"
          },
          "utmCampaign": {
            "maxLength": 150,
            "type": "string",
            "description": "The UTM campaign the transaction is tracked against. This is free text and is unrelated to\r\n`campaign` and `campaignId`.\r\n<ul><li>Optional. Maximum 150 characters.</li></ul>",
            "nullable": true,
            "example": "summer-appeal-2026"
          },
          "giftAid": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.GiftAidApiRequest"
              }
            ],
            "description": "The Gift Aid declaration to record for the constituent of the transaction.\r\n<ul><li>Optional. Whether tax can be recovered on the money is set per allocation, as `allocations[].canRecoverTax`.</li></ul>",
            "nullable": true
          },
          "allocations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.AllocationApiRequest"
            },
            "description": "How the payment is allocated.\r\n<ul><li>Required; at least one allocation.</li><li>The allocation amounts must add up to `amount`.</li></ul>"
          }
        },
        "description": "The payment and its allocations to add to a constituent."
      },
      "Transactions.GiftAidApiRequest": {
        "type": "object",
        "properties": {
          "addDeclaration": {
            "type": "boolean",
            "description": "Whether a Gift Aid declaration is created for the constituent of the transaction.\r\n<ul><li>Optional; defaults to `false`.</li><li>Cannot be combined with `isAnonymousTransaction`, as there is no constituent to declare for.</li><li>Nothing is created when the constituent already has an active declaration.</li><li>The declaration is created once the transaction has been written, so the transaction is still returned when the declaration cannot be created.</li></ul>",
            "nullable": true,
            "example": true
          },
          "declarationMethod": {
            "type": "string",
            "description": "How the declaration was given.\r\n<ul><li>Optional; defaults to `Web`. Only allowed together with `addDeclaration`.</li><li>Must match the description of a value in the `Gift Aid Declaration Methods` lookup.</li></ul>",
            "nullable": true,
            "example": "Web"
          },
          "claimed": {
            "type": "boolean",
            "description": "Whether the tax on the transaction has already been claimed outside Donorfy.\r\n<ul><li>Optional; defaults to `false`.</li><li>When `true`, tax cannot be recovered on any of the allocations, whatever\r\n`allocations[].canRecoverTax` asks for, so that Donorfy does not claim the tax a second\r\ntime.</li></ul>",
            "nullable": true,
            "example": true
          },
          "amountClaimed": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "The tax already claimed on the transaction elsewhere, in the currency of the transaction.\r\n<ul><li>Optional; defaults to `0`. Only allowed together with `claimed`.</li><li>Cannot be negative.</li></ul>",
            "format": "double",
            "example": 25.00
          }
        },
        "description": "The Gift Aid of the transaction: the declaration to record for its constituent, and whether its\r\ntax has already been claimed elsewhere."
      },
      "Transactions.InvalidRequest": {
        "required": [
          "message",
          "errors"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Summary of why the request was rejected."
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.ValidationItem"
            },
            "description": "The individual validation failures of the request; empty when the failure is not specific to a\r\nsingle field."
          }
        },
        "description": "The body returned when a request is rejected because it is not valid."
      },
      "Transactions.MainContactApiRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "The title of the main contact.",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "The first name of the main contact. Required.",
            "nullable": true,
            "example": "Jane"
          },
          "lastName": {
            "type": "string",
            "description": "The last name of the main contact. Required.",
            "nullable": true,
            "example": "Smith"
          },
          "middleName": {
            "type": "string",
            "description": "The middle name of the main contact.",
            "nullable": true,
            "example": "Elizabeth"
          },
          "prefix": {
            "type": "string",
            "description": "The name prefix used when addressing the main contact.",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "The letters or honours that follow the name of the main contact.",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "The previous name of the main contact.",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "The informal or alternative name the main contact is known by.",
            "nullable": true,
            "example": "Janey"
          },
          "gender": {
            "type": "string",
            "description": "The gender of the main contact. Accepts the identifier or the description of an active value\r\nin the `Genders` lookup.",
            "nullable": true,
            "example": "Female"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "The date of birth of the main contact, in ISO 8601 format (yyyy-MM-dd).",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name of the main contact may be swapped when Donorfy detects they\r\nwere entered the wrong way round.",
            "nullable": true,
            "example": false
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the main contact must be excluded from Gift Aid claims. Defaults to `false`,\r\nwhatever the group holds.",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "The identifier of the main contact in the system that owns the data outside Donorfy. The\r\nexternal key of the group is not copied to it.",
            "nullable": true,
            "example": "CRM-00012346"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "The national identification number of the main contact, for example a National Insurance\r\nnumber.",
            "nullable": true,
            "example": "QQ123456C"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "The campaign the main contact was recruited by. Accepts the identifier or the name of an\r\nexisting campaign. The recruitment campaign of the group is not copied to it.",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "The identifier of the campaign the main contact was recruited by. Takes precedence over\r\n`recruitmentCampaign`.",
            "format": "uuid",
            "nullable": true,
            "example": "9fd8f40c-6df1-ec11-b5cf-0003ff444e27"
          },
          "jobTitle": {
            "type": "string",
            "description": "The job title of the main contact. Stored on its main contact details.",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "The department of the main contact. Stored on its main contact details.",
            "nullable": true,
            "example": "Fundraising"
          },
          "salutation": {
            "type": "string",
            "description": "How the main contact is addressed in correspondence. Stored on its main contact details.",
            "nullable": true,
            "example": "Dear Jane"
          },
          "labelName": {
            "type": "string",
            "description": "The name used on labels and envelopes for the main contact. Stored on its main contact\r\ndetails.",
            "nullable": true,
            "example": "Mrs J Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "The number or name of the house or building of the main contact. Left empty when it is not\r\nsupplied: the address of the group is not copied to the main contact details of the main\r\ncontact.",
            "nullable": true,
            "example": "14"
          },
          "addressLine1": {
            "type": "string",
            "description": "The first line of the address of the main contact.",
            "nullable": true,
            "example": "High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "The second line of the address of the main contact.",
            "nullable": true,
            "example": "Kingswood"
          },
          "town": {
            "type": "string",
            "description": "The town or city of the address of the main contact.",
            "nullable": true,
            "example": "Bristol"
          },
          "county": {
            "type": "string",
            "description": "The county of the address of the main contact.",
            "nullable": true,
            "example": "Somerset"
          },
          "postalCode": {
            "type": "string",
            "description": "The postal or zip code of the address of the main contact.",
            "nullable": true,
            "example": "BS15 1AA"
          },
          "country": {
            "type": "string",
            "description": "The country of the address of the main contact. Accepts the identifier or the description of\r\nan active value in the `Countries` lookup.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "phone1": {
            "type": "string",
            "description": "The main telephone number of the main contact.",
            "nullable": true,
            "example": "01179 000000"
          },
          "phone2": {
            "type": "string",
            "description": "A second telephone number of the main contact.",
            "nullable": true,
            "example": "01179 000001"
          },
          "mobilePhone": {
            "type": "string",
            "description": "The mobile telephone number of the main contact.",
            "nullable": true,
            "example": "07700 900000"
          },
          "email1Address": {
            "type": "string",
            "description": "The main email address of the main contact.",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "The format emails to the main address of the main contact are sent in.",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "A second email address of the main contact.",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "The format emails to the second address of the main contact are sent in.",
            "nullable": true,
            "example": "Text"
          },
          "channelPreferences": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.ChannelPreferencesApiRequest"
              }
            ],
            "description": "The keep in touch preferences of the main contact, given per channel as `email`,\r\n`phone`, `mail` and `sms`. Recorded against the main contact alone, defaulting\r\nto its own recruitment campaign.",
            "nullable": true
          }
        },
        "description": "The individual to create as the main contact of the group the transaction is attached to."
      },
      "Transactions.NewConstituentApiRequest": {
        "type": "object",
        "properties": {
          "constituentType": {
            "type": "string",
            "description": "The type of constituent to create.\r\n<ul><li>Required.</li><li>Must match the description of an active value in the `Constituent Types` lookup.</li><li>Types flagged as a group (for example `Organisation`) accept `organisationName`; all other types reject it.</li></ul>",
            "nullable": true,
            "example": "Individual"
          },
          "gender": {
            "type": "string",
            "description": "The gender of the constituent.\r\n<ul><li>Optional; rejected for a group type, where it is supplied in `mainContact` instead.</li><li>Must match the description of an active value in the `Genders` lookup.</li></ul>",
            "nullable": true,
            "example": "Female"
          },
          "organisationName": {
            "type": "string",
            "description": "The name of the organisation, trust or other group.\r\n<ul><li>Only allowed when `constituentType` is a group type; otherwise the request is rejected. The legacy API stored it on an individual as well, so this is a breaking change in v1.</li><li>Maximum 250 characters.</li></ul>",
            "nullable": true,
            "example": "The Access Group"
          },
          "title": {
            "type": "string",
            "description": "The title of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Mrs"
          },
          "firstName": {
            "type": "string",
            "description": "The first name of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Jane"
          },
          "middleName": {
            "type": "string",
            "description": "The middle name of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Elizabeth"
          },
          "lastName": {
            "type": "string",
            "description": "The last name of the person.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Smith"
          },
          "prefix": {
            "type": "string",
            "description": "The name prefix used when addressing the constituent.\r\n<ul><li>Optional. Maximum 50 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Dr"
          },
          "suffix": {
            "type": "string",
            "description": "The letters or honours that follow the name of the constituent.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "OBE"
          },
          "formerly": {
            "type": "string",
            "description": "The previous name of the constituent.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Jane Brown"
          },
          "alsoKnownAs": {
            "type": "string",
            "description": "The informal or alternative name the constituent is known by.\r\n<ul><li>Optional. Maximum 100 characters.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": "Janey"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "The date of birth of the constituent.\r\n<ul><li>Optional. Date in ISO 8601 format (yyyy-MM-dd).</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "format": "date",
            "nullable": true,
            "example": "1975-04-23"
          },
          "allowNameSwap": {
            "type": "boolean",
            "description": "Whether the first and last name may be swapped when Donorfy detects they were entered the wrong way round.\r\n<ul><li>Optional; defaults to `false` when not supplied.</li><li>Rejected for a group type; supply it in `mainContact` instead.</li></ul>",
            "nullable": true,
            "example": false
          },
          "noGiftAid": {
            "type": "boolean",
            "description": "Whether the constituent must be excluded from Gift Aid claims.\r\n<ul><li>Optional; defaults to `false` when not supplied.</li></ul>",
            "nullable": true,
            "example": false
          },
          "externalKey": {
            "type": "string",
            "description": "The identifier of the constituent in the system that owns the data outside Donorfy.\r\n<ul><li>Optional. Maximum 50 characters.</li></ul>",
            "nullable": true,
            "example": "CRM-00012345"
          },
          "nationalIDNumber": {
            "type": "string",
            "description": "The national identification number of the constituent, for example a National Insurance number.\r\n<ul><li>Optional. Maximum 50 characters.</li><li>Stored as it is given. The `AccessNationalIdentity` role is only needed to read it back or to change it later.</li></ul>",
            "nullable": true,
            "example": "QQ123456C"
          },
          "recruitmentCampaign": {
            "type": "string",
            "description": "The campaign the constituent was recruited by.\r\n<ul><li>Optional. Accepts the identifier or the name of an existing campaign.</li><li>Also recorded against the channel preferences created with the constituent.</li></ul>",
            "nullable": true,
            "example": "Spring Appeal 2026"
          },
          "recruitmentCampaignId": {
            "type": "string",
            "description": "The identifier of the campaign the constituent was recruited by.\r\n<ul><li>Optional; takes precedence over `recruitmentCampaign`.</li><li>Must be an existing campaign.</li><li>Also recorded against the channel preferences created with the constituent.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "9fd8f40c-6df1-ec11-b5cf-0003ff444e27"
          },
          "jobTitle": {
            "type": "string",
            "description": "The job title of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "Head of Fundraising"
          },
          "department": {
            "type": "string",
            "description": "The department of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "Fundraising"
          },
          "salutation": {
            "type": "string",
            "description": "How the constituent is addressed in correspondence. Stored on the main contact details.",
            "nullable": true,
            "example": "Dear Jane"
          },
          "labelName": {
            "type": "string",
            "description": "The name used on labels and envelopes. Stored on the main contact details.",
            "nullable": true,
            "example": "Mrs J Smith"
          },
          "houseBuildingNumber": {
            "type": "string",
            "description": "The number or name of the house or building. Stored on the main contact details.",
            "nullable": true,
            "example": "14"
          },
          "addressLine1": {
            "type": "string",
            "description": "The first line of the address. Stored on the main contact details.",
            "nullable": true,
            "example": "High Street"
          },
          "addressLine2": {
            "type": "string",
            "description": "The second line of the address. Stored on the main contact details.",
            "nullable": true,
            "example": "Kingswood"
          },
          "town": {
            "type": "string",
            "description": "The town or city of the address. Stored on the main contact details.",
            "nullable": true,
            "example": "Bristol"
          },
          "county": {
            "type": "string",
            "description": "The county of the address. Stored on the main contact details.",
            "nullable": true,
            "example": "Somerset"
          },
          "country": {
            "type": "string",
            "description": "The country of the address. Accepts the identifier or the description of an active value in\r\nthe `Countries` lookup. Stored on the main contact details.",
            "nullable": true,
            "example": "United Kingdom"
          },
          "postalCode": {
            "type": "string",
            "description": "The postal or zip code of the address. Stored on the main contact details.",
            "nullable": true,
            "example": "BS15 1AA"
          },
          "phone1": {
            "type": "string",
            "description": "The main telephone number of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "01179 000000"
          },
          "phone2": {
            "type": "string",
            "description": "A second telephone number of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "01179 000001"
          },
          "mobilePhone": {
            "type": "string",
            "description": "The mobile telephone number of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "07700 900000"
          },
          "email1Address": {
            "type": "string",
            "description": "The main email address of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "jane.smith@example.com"
          },
          "email1Format": {
            "type": "string",
            "description": "The format emails to the main address are sent in. Stored on the main contact details.",
            "nullable": true,
            "example": "HTML"
          },
          "email2Address": {
            "type": "string",
            "description": "A second email address of the constituent. Stored on the main contact details.",
            "nullable": true,
            "example": "jane@example.org"
          },
          "email2Format": {
            "type": "string",
            "description": "The format emails to the second address are sent in. Stored on the main contact details.",
            "nullable": true,
            "example": "Text"
          },
          "linkedToConstituentId": {
            "type": "string",
            "description": "The constituent whose address the main contact details are linked to.",
            "format": "uuid",
            "nullable": true,
            "example": "6f9619ff-8b86-d011-b42d-00cf4fc964ff"
          },
          "channelPreferences": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.ChannelPreferencesApiRequest"
              }
            ],
            "description": "The keep in touch preferences of the constituent, given per channel as `email`,\r\n`phone`, `mail` and `sms`.\r\n<ul><li>Optional; a channel that is left out, like the whole object when it is omitted, is recorded unconfirmed and reads back with a `preferenceAllowed` of `null`.</li><li>Recorded against this constituent alone; the preferences of a `mainContact` are supplied inside it.</li></ul>",
            "nullable": true
          },
          "mainContact": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.MainContactApiRequest"
              }
            ],
            "description": "The individual to create as the main contact of the group.\r\n<ul><li>Optional; only accepted when `constituentType` is a group type, and rejected otherwise.</li><li>`firstName` and `lastName` are required inside it.</li><li>Two constituents are created: the group the transaction is attached to, and the individual whose ID is returned as `mainContactConstituentId`.</li><li>Nothing is copied from the group: the campaign, `noGiftAid`, `externalKey`, the channel preferences and the contact detail properties of the main contact are the ones supplied inside it.</li></ul>",
            "nullable": true
          }
        },
        "description": "The details of the constituent to create and attach the transaction to."
      },
      "Transactions.SoftCreditApiResponse": {
        "type": "object",
        "properties": {
          "constituentId": {
            "type": "string",
            "description": "Unique identifier of the constituent that was soft credited.",
            "format": "uuid",
            "nullable": true,
            "example": "9a4d1c02-6f2b-4d9f-8a1e-5c7b0f3d2e11"
          },
          "constituentDescription": {
            "type": "string",
            "description": "Name of the constituent that was soft credited.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Amount the constituent was soft credited with.\r\n<ul><li>Null when the soft credit was recorded without an amount.</li></ul>",
            "format": "double",
            "example": 250.00
          },
          "comments": {
            "type": "string",
            "description": "Comments recorded against the soft credit.",
            "nullable": true,
            "example": "Secured through the local fundraising group"
          }
        },
        "description": "A constituent soft credited with the payment, recognising them for a gift they brought in\r\nwithout the money coming from them."
      },
      "Transactions.TrackingCodeApiResponse": {
        "type": "object",
        "properties": {
          "utmSource": {
            "type": "string",
            "description": "Referrer that sent the donor, from the `utm_source` parameter.",
            "nullable": true,
            "example": "google"
          },
          "utmMedium": {
            "type": "string",
            "description": "Marketing medium that sent the donor, from the `utm_medium` parameter.",
            "nullable": true,
            "example": "cpc"
          },
          "utmTerm": {
            "type": "string",
            "description": "Paid search keyword the donor arrived on, from the `utm_term` parameter.",
            "nullable": true,
            "example": "donate to charity"
          },
          "utmContent": {
            "type": "string",
            "description": "Variant of the advert or link that was used, from the `utm_content` parameter.",
            "nullable": true,
            "example": "banner-a"
          },
          "utmCampaign": {
            "type": "string",
            "description": "Marketing campaign the donor came from, from the `utm_campaign` parameter.",
            "nullable": true,
            "example": "spring-appeal-2026"
          }
        },
        "description": "The UTM tracking codes captured for a transaction, describing where it came from."
      },
      "Transactions.TransactionAllocationApiResponse": {
        "type": "object",
        "properties": {
          "allocationId": {
            "type": "string",
            "description": "Unique identifier of the allocation.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "transactionNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the allocation.\r\n<ul><li>Taken from your transaction counter, so it differs from the number of the payment.</li></ul>",
            "format": "int64",
            "example": 10433
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Amount allocated.",
            "format": "double",
            "example": 25.00
          },
          "quantity": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Quantity recorded alongside the amount.\r\n<ul><li>Never multiplies the amount; defaults to 1.</li></ul>",
            "format": "double",
            "example": 1
          },
          "accountingDate": {
            "type": "string",
            "description": "Date the allocation is recognised on.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15"
          },
          "dateDue": {
            "type": "string",
            "description": "Date the allocation is due.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15"
          },
          "product": {
            "type": "string",
            "description": "Product the allocation is attributed to.",
            "nullable": true,
            "example": "Donation"
          },
          "productId": {
            "type": "string",
            "description": "Unique identifier of the product.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "fund": {
            "type": "string",
            "description": "Fund the allocation is attributed to.",
            "nullable": true,
            "example": "General Fund"
          },
          "fundId": {
            "type": "string",
            "description": "Unique identifier of the fund.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "department": {
            "type": "string",
            "description": "Department the allocation is attributed to.",
            "nullable": true,
            "example": "Fundraising"
          },
          "departmentId": {
            "type": "string",
            "description": "Unique identifier of the department.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "canRecoverTax": {
            "type": "boolean",
            "description": "Whether Gift Aid can be recovered on the allocation.",
            "nullable": true,
            "example": true
          },
          "comments": {
            "type": "string",
            "description": "Comments recorded against the allocation.",
            "nullable": true,
            "example": "Restricted to the appeal"
          },
          "beneficiaryConstituentId": {
            "type": "string",
            "description": "Constituent the allocation benefits, when it is not the donor.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "beneficiaryConstituentDescription": {
            "type": "string",
            "description": "Name of the constituent the allocation benefits.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "accountDownloadCode1": {
            "type": "string",
            "description": "First account download code of the allocation.",
            "nullable": true,
            "example": "4001"
          },
          "accountDownloadCode2": {
            "type": "string",
            "description": "Second account download code of the allocation.",
            "nullable": true,
            "example": "DEPT1"
          },
          "accountDownloadCode3": {
            "type": "string",
            "description": "Third account download code of the allocation.",
            "nullable": true,
            "example": "PROJ1"
          }
        },
        "description": "An allocation of a payment to a product and fund."
      },
      "Transactions.TransactionApiInclude": {
        "enum": [
          "trackingCodes",
          "softCredits"
        ],
        "type": "string",
        "description": "The related resources that can be expanded when retrieving a transaction.\n\nValues: trackingCodes, softCredits. Send the value, not the integer it stands for. Integers are still accepted for compatibility: trackingCodes = 0, softCredits = 1."
      },
      "Transactions.TransactionApiResponse": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string",
            "description": "Unique identifier of the payment.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "transactionNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the payment.",
            "format": "int64",
            "example": 10432
          },
          "constituentId": {
            "type": "string",
            "description": "Constituent that made the payment.\r\n<ul><li>Empty for an anonymous payment.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the constituent that made the payment.",
            "format": "int64",
            "example": 10432
          },
          "constituentDescription": {
            "type": "string",
            "description": "Name of the constituent that made the payment.\r\n<ul><li>`Anonymous` when the payment has no constituent.</li></ul>",
            "nullable": true,
            "example": "Jane Smith"
          },
          "isAnonymousTransaction": {
            "type": "boolean",
            "description": "Whether the payment was made anonymously.",
            "example": false
          },
          "connectedConstituentId": {
            "type": "string",
            "description": "Constituent the payment was connected to, when one was supplied.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "connectedConstituentDescription": {
            "type": "string",
            "description": "Name of the constituent the payment was connected to.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "fundraisingPageId": {
            "type": "string",
            "description": "Fundraising page the payment was attributed to, when one was supplied.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Amount of the payment.",
            "format": "double",
            "example": 25.00
          },
          "currency": {
            "type": "string",
            "description": "Currency of the payment.",
            "nullable": true,
            "example": "GBP"
          },
          "currencyId": {
            "type": "string",
            "description": "Unique identifier of the currency.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "paymentMethod": {
            "type": "string",
            "description": "Method the payment was made by.",
            "nullable": true,
            "example": "Direct Debit"
          },
          "paymentMethodId": {
            "type": "string",
            "description": "Unique identifier of the payment method.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaign": {
            "type": "string",
            "description": "Campaign the payment is attributed to.",
            "nullable": true,
            "example": "Winter Appeal"
          },
          "campaignId": {
            "type": "string",
            "description": "Unique identifier of the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "channel": {
            "type": "string",
            "description": "Channel the payment came through.",
            "nullable": true,
            "example": "Online"
          },
          "channelId": {
            "type": "string",
            "description": "Unique identifier of the channel.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "acknowledgement": {
            "type": "string",
            "description": "Acknowledgement sent for the payment.",
            "nullable": true,
            "example": "Thank you letter"
          },
          "acknowledgementId": {
            "type": "string",
            "description": "Unique identifier of the acknowledgement.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "bankAccount": {
            "type": "string",
            "description": "Bank account the payment was paid into.",
            "nullable": true,
            "example": "Main Current Account"
          },
          "bankAccountId": {
            "type": "string",
            "description": "Unique identifier of the bank account.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "acknowledgementText": {
            "type": "string",
            "description": "Text recorded with the acknowledgement of the payment.",
            "nullable": true,
            "example": "Sent 2025-01-20"
          },
          "reference": {
            "type": "string",
            "description": "Reference recorded against the payment.",
            "nullable": true,
            "example": "CHQ-1042"
          },
          "payoutReference": {
            "type": "string",
            "description": "Reference of the payout the payment was settled in.",
            "nullable": true,
            "example": "PO-2025-01-31"
          },
          "comments": {
            "type": "string",
            "description": "Comments recorded against the payment.",
            "nullable": true,
            "example": "Given at the winter event"
          },
          "enteredByUser": {
            "type": "string",
            "description": "User that entered the payment.",
            "nullable": true,
            "example": "jane.smith@example.org"
          },
          "transactionStatus": {
            "type": "string",
            "description": "Status of the payment.",
            "nullable": true,
            "example": "Paid"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the payment is active.",
            "nullable": true,
            "example": true
          },
          "datePaid": {
            "type": "string",
            "description": "Date the payment was paid.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15"
          },
          "dateTimePaid": {
            "type": "string",
            "description": "Date and time the payment was paid.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T10:32:00Z"
          },
          "acknowledgedOn": {
            "type": "string",
            "description": "Date the payment was acknowledged on.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-20"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the payment was added.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T10:32:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the payment was last changed.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-16T09:04:00Z"
          },
          "processingCostsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Costs deducted from the payment by the processor.",
            "format": "double",
            "example": 0.54
          },
          "giftAidStatus": {
            "type": "string",
            "description": "Gift Aid status of the payment.",
            "nullable": true,
            "example": "Claimed"
          },
          "giftAidStatusDetails": {
            "type": "string",
            "description": "Detail recorded alongside the Gift Aid status of the payment, such as why it cannot be\r\nclaimed.",
            "nullable": true,
            "example": "No declaration held"
          },
          "giftAidAmountClaimed": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Gift Aid claimed on the payment.",
            "format": "double",
            "example": 6.25
          },
          "isRecurringGift": {
            "type": "boolean",
            "description": "Whether the payment is flagged as a recurring gift.",
            "example": false
          },
          "isRecurringPayment": {
            "type": "boolean",
            "description": "Whether the payment was collected by a recurring payment instruction.",
            "example": true
          },
          "recurringPaymentInstructionId": {
            "type": "string",
            "description": "Recurring payment instruction that collected the payment.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "allocations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.TransactionAllocationApiResponse"
            },
            "description": "Allocations splitting the payment across products and funds.\r\n<ul><li>Always returned when a single payment is retrieved.</li><li>When payments are listed, only returned when asked for with\r\n`include=allocations`.</li></ul>",
            "nullable": true
          }
        },
        "description": "A payment recorded against a constituent."
      },
      "Transactions.TransactionApiSort": {
        "enum": [
          "datePaid",
          "transactionNumber",
          "dateAdded",
          "dateChanged",
          "amount",
          "transactionStatus",
          "dateTimePaid",
          "acknowledgedOn",
          "constituentDescription",
          "constituentNumber",
          "campaign",
          "paymentMethod",
          "currency",
          "channel",
          "bankAccount",
          "acknowledgement",
          "reference",
          "payoutReference",
          "giftAidStatus",
          "giftAidAmountClaimed",
          "processingCostsAmount"
        ],
        "type": "string",
        "description": "The fields a list of transactions can be sorted by.\n\nValues: datePaid, transactionNumber, dateAdded, dateChanged, amount, transactionStatus, dateTimePaid, acknowledgedOn, constituentDescription, constituentNumber, campaign, paymentMethod, currency, channel, bankAccount, acknowledgement, reference, payoutReference, giftAidStatus, giftAidAmountClaimed, processingCostsAmount. Send the value, not the integer it stands for. Integers are still accepted for compatibility: datePaid = 0, transactionNumber = 1, dateAdded = 2, dateChanged = 3, amount = 4, transactionStatus = 5, dateTimePaid = 6, acknowledgedOn = 7, constituentDescription = 8, constituentNumber = 9, campaign = 10, paymentMethod = 11, currency = 12, channel = 13, bankAccount = 14, acknowledgement = 15, reference = 16, payoutReference = 17, giftAidStatus = 18, giftAidAmountClaimed = 19, processingCostsAmount = 20."
      },
      "Transactions.TransactionDefaultApiResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifier of the default value.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "description": {
            "type": "string",
            "description": "Description of the default value, as it is shown to users.",
            "nullable": true,
            "example": "Direct Mail"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the default value is active. `null` when the value does not record a state,\r\nwhich clients read as active.",
            "nullable": true,
            "example": true
          }
        },
        "description": "A single transaction entry default."
      },
      "Transactions.TransactionDefaultsApiResponse": {
        "type": "object",
        "properties": {
          "product": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default product of a transaction.",
            "nullable": true
          },
          "bankAccount": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default bank account of a transaction.",
            "nullable": true
          },
          "campaign": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default campaign of a transaction.",
            "nullable": true
          },
          "channel": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default campaign channel of a transaction.",
            "nullable": true
          },
          "fund": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default fund of a transaction.",
            "nullable": true
          },
          "department": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default department of a transaction.",
            "nullable": true
          },
          "paymentMethod": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default payment method of a transaction.",
            "nullable": true
          },
          "emailAcknowledgement": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default acknowledgement sent by email for a transaction.",
            "nullable": true
          },
          "mailAcknowledgement": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default acknowledgement sent by mail for a transaction.",
            "nullable": true
          },
          "currency": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TransactionDefaultApiResponse"
              }
            ],
            "description": "Default currency of a transaction.",
            "nullable": true
          }
        },
        "description": "The transaction entry defaults of a Donorfy instance — the values a new transaction is\r\npreselected with. Every property is always returned, and is `null` when that default is\r\nnot configured or when the value it names no longer exists. A configured default can be\r\ninactive and is still returned."
      },
      "Transactions.TransactionDetailApiResponse": {
        "type": "object",
        "properties": {
          "transactionId": {
            "type": "string",
            "description": "Unique identifier of the payment.",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "transactionNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the payment.",
            "format": "int64",
            "example": 10432
          },
          "constituentId": {
            "type": "string",
            "description": "Constituent that made the payment.\r\n<ul><li>Empty for an anonymous payment.</li></ul>",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "constituentNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "description": "Sequential number of the constituent that made the payment.",
            "format": "int64",
            "example": 10432
          },
          "constituentDescription": {
            "type": "string",
            "description": "Name of the constituent that made the payment.\r\n<ul><li>`Anonymous` when the payment has no constituent.</li></ul>",
            "nullable": true,
            "example": "Jane Smith"
          },
          "isAnonymousTransaction": {
            "type": "boolean",
            "description": "Whether the payment was made anonymously.",
            "example": false
          },
          "connectedConstituentId": {
            "type": "string",
            "description": "Constituent the payment was connected to, when one was supplied.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "connectedConstituentDescription": {
            "type": "string",
            "description": "Name of the constituent the payment was connected to.",
            "nullable": true,
            "example": "Jane Smith"
          },
          "fundraisingPageId": {
            "type": "string",
            "description": "Fundraising page the payment was attributed to, when one was supplied.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Amount of the payment.",
            "format": "double",
            "example": 25.00
          },
          "currency": {
            "type": "string",
            "description": "Currency of the payment.",
            "nullable": true,
            "example": "GBP"
          },
          "currencyId": {
            "type": "string",
            "description": "Unique identifier of the currency.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "paymentMethod": {
            "type": "string",
            "description": "Method the payment was made by.",
            "nullable": true,
            "example": "Direct Debit"
          },
          "paymentMethodId": {
            "type": "string",
            "description": "Unique identifier of the payment method.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "campaign": {
            "type": "string",
            "description": "Campaign the payment is attributed to.",
            "nullable": true,
            "example": "Winter Appeal"
          },
          "campaignId": {
            "type": "string",
            "description": "Unique identifier of the campaign.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "channel": {
            "type": "string",
            "description": "Channel the payment came through.",
            "nullable": true,
            "example": "Online"
          },
          "channelId": {
            "type": "string",
            "description": "Unique identifier of the channel.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "acknowledgement": {
            "type": "string",
            "description": "Acknowledgement sent for the payment.",
            "nullable": true,
            "example": "Thank you letter"
          },
          "acknowledgementId": {
            "type": "string",
            "description": "Unique identifier of the acknowledgement.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "bankAccount": {
            "type": "string",
            "description": "Bank account the payment was paid into.",
            "nullable": true,
            "example": "Main Current Account"
          },
          "bankAccountId": {
            "type": "string",
            "description": "Unique identifier of the bank account.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "acknowledgementText": {
            "type": "string",
            "description": "Text recorded with the acknowledgement of the payment.",
            "nullable": true,
            "example": "Sent 2025-01-20"
          },
          "reference": {
            "type": "string",
            "description": "Reference recorded against the payment.",
            "nullable": true,
            "example": "CHQ-1042"
          },
          "payoutReference": {
            "type": "string",
            "description": "Reference of the payout the payment was settled in.",
            "nullable": true,
            "example": "PO-2025-01-31"
          },
          "comments": {
            "type": "string",
            "description": "Comments recorded against the payment.",
            "nullable": true,
            "example": "Given at the winter event"
          },
          "enteredByUser": {
            "type": "string",
            "description": "User that entered the payment.",
            "nullable": true,
            "example": "jane.smith@example.org"
          },
          "transactionStatus": {
            "type": "string",
            "description": "Status of the payment.",
            "nullable": true,
            "example": "Paid"
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the payment is active.",
            "nullable": true,
            "example": true
          },
          "datePaid": {
            "type": "string",
            "description": "Date the payment was paid.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15"
          },
          "dateTimePaid": {
            "type": "string",
            "description": "Date and time the payment was paid.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T10:32:00Z"
          },
          "acknowledgedOn": {
            "type": "string",
            "description": "Date the payment was acknowledged on.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-20"
          },
          "dateAdded": {
            "type": "string",
            "description": "Date and time the payment was added.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-15T10:32:00Z"
          },
          "dateChanged": {
            "type": "string",
            "description": "Date and time the payment was last changed.",
            "format": "date-time",
            "nullable": true,
            "example": "2025-01-16T09:04:00Z"
          },
          "processingCostsAmount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Costs deducted from the payment by the processor.",
            "format": "double",
            "example": 0.54
          },
          "giftAidStatus": {
            "type": "string",
            "description": "Gift Aid status of the payment.",
            "nullable": true,
            "example": "Claimed"
          },
          "giftAidStatusDetails": {
            "type": "string",
            "description": "Detail recorded alongside the Gift Aid status of the payment, such as why it cannot be\r\nclaimed.",
            "nullable": true,
            "example": "No declaration held"
          },
          "giftAidAmountClaimed": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "description": "Gift Aid claimed on the payment.",
            "format": "double",
            "example": 6.25
          },
          "isRecurringGift": {
            "type": "boolean",
            "description": "Whether the payment is flagged as a recurring gift.",
            "example": false
          },
          "isRecurringPayment": {
            "type": "boolean",
            "description": "Whether the payment was collected by a recurring payment instruction.",
            "example": true
          },
          "recurringPaymentInstructionId": {
            "type": "string",
            "description": "Recurring payment instruction that collected the payment.",
            "format": "uuid",
            "nullable": true,
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "allocations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.TransactionAllocationApiResponse"
            },
            "description": "Allocations splitting the payment across products and funds.\r\n<ul><li>Always returned when a single payment is retrieved.</li><li>When payments are listed, only returned when asked for with\r\n`include=allocations`.</li></ul>",
            "nullable": true
          },
          "trackingCodes": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Transactions.TrackingCodeApiResponse"
              }
            ],
            "description": "The UTM tracking codes captured for the payment.\r\n<ul><li>Returned only when `include=trackingCodes` is supplied.</li><li>Omitted when neither the payment nor the constituent that paid carries any.</li></ul>",
            "nullable": true
          },
          "softCredits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transactions.SoftCreditApiResponse"
            },
            "description": "The constituents soft credited with the payment.\r\n<ul><li>Returned only when `include=softCredits` is supplied.</li></ul>",
            "nullable": true
          }
        },
        "description": "A single payment together with the related resources that were requested with `include`."
      },
      "Transactions.TransactionListApiInclude": {
        "enum": [
          "allocations"
        ],
        "type": "string",
        "description": "The related resources that can be expanded when listing transactions.\n\nValues: allocations. Send the value, not the integer it stands for. Integers are still accepted for compatibility: allocations = 0."
      },
      "Transactions.ValidationItem": {
        "required": [
          "message",
          "field"
        ],
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Description of what is wrong with the value."
          },
          "field": {
            "type": "string",
            "description": "Name of the field the failure relates to."
          }
        },
        "description": "A single validation failure of a request."
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Access Identity access token of the user, for interactive callers (example: 'Bearer 12345abcdef'). Send the X-InstanceId header with it.",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "InstanceId": {
        "type": "apiKey",
        "description": "ApplicationSubscriptionId of the Donorfy instance the request is for. Required alongside the Bearer token.",
        "name": "X-InstanceId",
        "in": "header"
      },
      "Basic": {
        "type": "http",
        "description": "Permission name and access key of a system integration, as base64(<PermissionName>:<AccessKey>). Send the X-API-Key header with it.",
        "scheme": "basic"
      },
      "ApiKey": {
        "type": "apiKey",
        "description": "Tenant code the request is for. Required alongside Basic authentication.",
        "name": "X-API-Key",
        "in": "header"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ],
      "InstanceId": [ ]
    },
    {
      "Basic": [ ],
      "ApiKey": [ ]
    }
  ],
  "tags": [
    {
      "name": "Activities",
      "description": "Activities recorded against constituents, such as phone calls, meetings and letters."
    },
    {
      "name": "Campaigns",
      "description": "Fundraising campaigns that income, activities and constituent recruitment are attributed to."
    },
    {
      "name": "Constituents",
      "description": "People, organisations and groups held in the CRM, including their core details, creation, deletion and duplicate checking."
    },
    {
      "name": "Constituents - Channel Preferences",
      "description": "The channels a constituent may, or may not, be contacted through."
    },
    {
      "name": "Constituents - Contact Details",
      "description": "Addresses, phone numbers, email addresses and channel preferences belonging to a constituent."
    },
    {
      "name": "Constituents - Tags",
      "description": "Tags allocated to a constituent, such as the interests and preferences recorded against it."
    },
    {
      "name": "Lists",
      "description": "Saved list definitions used to segment data, together with the runs that execute them and their results."
    },
    {
      "name": "Lists - Runs",
      "description": "Executions of a list definition and the results they produced."
    },
    {
      "name": "Lists - Types",
      "description": "The kinds of record a list definition can return (for example constituents or transactions)."
    },
    {
      "name": "Lookup Types",
      "description": "Categories of configurable reference data (for example payment methods or activity types)."
    },
    {
      "name": "Lookups",
      "description": "The individual reference data values belonging to a lookup type."
    },
    {
      "name": "Transactions",
      "description": "Payments recorded against a constituent and the allocations that split them across products and funds."
    },
    {
      "name": "Hidden",
      "description": "Internal endpoints serving the Donorfy clients. They are not part of the public API and are not documented outside the non-production environments."
    }
  ]
}