{
  "components": {
    "schemas": {
      "Address": {
        "additionalProperties": false,
        "properties": {
          "addition": {
            "description": "Additional address info.",
            "type": "string"
          },
          "building": {
            "description": "Building name or identifier.",
            "type": "string"
          },
          "building_type": {
            "description": "Type of building.",
            "enum": [
              "house",
              "apartment",
              "office",
              "other"
            ],
            "type": "string"
          },
          "city": {
            "description": "City name.",
            "examples": [
              "Paris"
            ],
            "type": "string"
          },
          "country": {
            "description": "Country.",
            "examples": [
              "France"
            ],
            "type": "string"
          },
          "county": {
            "description": "County or department.",
            "type": "string"
          },
          "door": {
            "description": "Door or apartment identifier.",
            "type": "string"
          },
          "floor": {
            "description": "Floor number.",
            "type": "string"
          },
          "house_number": {
            "description": "Street number.",
            "examples": [
              "12"
            ],
            "type": "string"
          },
          "id": {
            "description": "Unique identifier of the address.",
            "examples": [
              7
            ],
            "format": "int64",
            "minimum": 0,
            "readOnly": true,
            "type": "integer"
          },
          "infos": {
            "description": "Additional address information.",
            "type": "string"
          },
          "latitude": {
            "description": "WGS-84 latitude.",
            "examples": [
              "48.8606"
            ],
            "type": "string"
          },
          "longitude": {
            "description": "WGS-84 longitude.",
            "examples": [
              "2.3376"
            ],
            "type": "string"
          },
          "postal_code": {
            "description": "Postal / ZIP code.",
            "examples": [
              "75001"
            ],
            "type": "string"
          },
          "state": {
            "description": "State or region.",
            "type": "string"
          },
          "street": {
            "description": "Street name.",
            "examples": [
              "Rue de Rivoli"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "AdvancedSearch": {
        "additionalProperties": false,
        "properties": {
          "page": {
            "description": "Page index (0-based).",
            "examples": [
              0
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "per_page": {
            "description": "Results per page.",
            "examples": [
              50
            ],
            "format": "int64",
            "maximum": 1000,
            "minimum": 1,
            "type": "integer"
          },
          "query": {
            "$ref": "#/components/schemas/AdvancedSearchQuery",
            "description": "Filter query tree."
          },
          "sort_asc": {
            "description": "Sort ascending.",
            "examples": [
              true
            ],
            "type": "boolean"
          },
          "sort_attr": {
            "description": "Field to sort by.",
            "enum": [
              "surname",
              "firstname",
              "birthdate",
              "gender",
              "lastchange",
              "mail",
              "married_name",
              "city"
            ],
            "examples": [
              "surname"
            ],
            "type": "string"
          }
        },
        "required": [
          "per_page"
        ],
        "type": "object"
      },
      "AdvancedSearchCondition": {
        "additionalProperties": false,
        "properties": {
          "attr": {
            "description": "Attribute to filter on.",
            "examples": [
              "city"
            ],
            "type": "string"
          },
          "form_id": {
            "description": "Form ID when filtering on contacts' formdata.",
            "examples": [
              123
            ],
            "format": "int64",
            "type": "integer"
          },
          "form_ref_ids": {
            "description": "Refvalue IDs when filtering on contacts' formdata.",
            "examples": [
              [
                1,
                2,
                3
              ]
            ],
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "from": {
            "description": "Lower bound of a range filter (inclusive)."
          },
          "ope": {
            "description": "Operator to apply on the attribute.",
            "enum": [
              "ext",
              "not_ext",
              "eql",
              "not_eql",
              "contains",
              "not_contains",
              "range",
              "lte",
              "gte"
            ],
            "examples": [
              "eql"
            ],
            "type": "string"
          },
          "to": {
            "description": "Upper bound of a range filter (inclusive)."
          },
          "value": {
            "description": "Value to compare the attribute against."
          }
        },
        "required": [
          "attr",
          "ope"
        ],
        "type": "object"
      },
      "AdvancedSearchQuery": {
        "oneOf": [
          {
            "additionalProperties": false,
            "description": "Every group/condition must be satisfied.",
            "properties": {
              "$all": {
                "description": "Condition groups (each group is a set of filters combined with AND or OR).",
                "items": {
                  "$ref": "#/components/schemas/SearchConditionGroup"
                },
                "type": "array"
              }
            },
            "required": [
              "$all"
            ],
            "title": "Match all (AND)",
            "type": "object"
          },
          {
            "additionalProperties": false,
            "description": "At least one group/condition must be satisfied.",
            "properties": {
              "$at_least_one": {
                "description": "Condition groups (each group is a set of filters combined with AND or OR).",
                "items": {
                  "$ref": "#/components/schemas/SearchConditionGroup"
                },
                "type": "array"
              }
            },
            "required": [
              "$at_least_one"
            ],
            "title": "Match at least one (OR)",
            "type": "object"
          }
        ]
      },
      "Batch": {
        "additionalProperties": false,
        "properties": {
          "closed": {
            "description": "Whether the batch is closed.",
            "type": "boolean"
          },
          "closed_at": {
            "description": "Batch close timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "delivered_at": {
            "description": "Batch delivery timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "delivery_token": {
            "description": "Batch delivery token.",
            "type": "string"
          },
          "display_name": {
            "description": "Batch display name.",
            "type": "string"
          },
          "full": {
            "description": "Whether the batch reached its maximum size.",
            "type": "boolean"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "summary": {
            "contentEncoding": "base64",
            "description": "Batch summary payload.",
            "type": "string"
          },
          "transaction_count": {
            "description": "Number of transactions in the batch.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/UserForTransaction",
            "description": "Associated user."
          },
          "user_id": {
            "description": "User identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "display_name",
          "closed",
          "full",
          "transaction_count",
          "user_id"
        ],
        "type": "object"
      },
      "CodeCampaign": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "description": "Campaign code.",
            "type": "string"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "code",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "Contact": {
        "additionalProperties": false,
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address",
            "description": "Postal address."
          },
          "age_category": {
            "description": "Age category.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "birth_city": {
            "description": "City of birth.",
            "type": "string"
          },
          "birth_country": {
            "description": "Country code of birth.",
            "type": "string"
          },
          "birthdate": {
            "description": "Date of birth.",
            "format": "date-time",
            "type": "string"
          },
          "black_list": {
            "description": "Whether the contact has opted out of communications.",
            "type": "boolean"
          },
          "created_at": {
            "description": "Timestamp when the contact was created.",
            "format": "date-time",
            "readOnly": true,
            "type": "string"
          },
          "custom_fields": {
            "description": "Organisation-defined custom fields.",
            "items": {
              "$ref": "#/components/schemas/CustomField"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "firstname": {
            "description": "First name.",
            "examples": [
              "Jane"
            ],
            "type": "string"
          },
          "formdatas": {
            "description": "Organisation-defined form data.",
            "items": {
              "$ref": "#/components/schemas/FormData"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "gender": {
            "description": "Gender. One of: M (Male), F (Female), O (Other). Empty if unknown.",
            "enum": [
              "M",
              "F",
              "O"
            ],
            "examples": [
              "female"
            ],
            "type": "string"
          },
          "id": {
            "description": "Unique identifier of the contact.",
            "format": "int64",
            "minimum": 0,
            "readOnly": true,
            "type": "integer"
          },
          "mail": {
            "description": "Primary email address.",
            "examples": [
              "jane@example.com"
            ],
            "format": "email",
            "type": "string"
          },
          "mobile": {
            "description": "Mobile phone number.",
            "type": "string"
          },
          "mobile_invalid": {
            "description": "Whether the mobile phone number is invalid.",
            "type": "boolean"
          },
          "nationality": {
            "description": "Nationality.",
            "type": "string"
          },
          "phone": {
            "description": "Landline phone number.",
            "type": "string"
          },
          "phone_invalid": {
            "description": "Whether the landline phone number is invalid.",
            "type": "boolean"
          },
          "surname": {
            "description": "Last (family) name.",
            "examples": [
              "Doe"
            ],
            "type": "string"
          },
          "tags": {
            "description": "Tags attached to the contact.",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "updated_at": {
            "description": "Timestamp when the contact was last updated.",
            "format": "date-time",
            "readOnly": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "ContactForTransaction": {
        "additionalProperties": false,
        "properties": {
          "firstname": {
            "description": "Contact first name.",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "membership_code": {
            "description": "Membership code.",
            "type": "string"
          },
          "membership_number": {
            "description": "Membership number.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "surname": {
            "description": "Contact surname.",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "ContactUpsertAddress": {
        "additionalProperties": false,
        "properties": {
          "addition": {
            "description": "Additional address line.",
            "type": "string"
          },
          "building": {
            "description": "Building identifier.",
            "type": "string"
          },
          "city": {
            "description": "City.",
            "type": "string"
          },
          "citycode": {
            "description": "City code.",
            "type": "string"
          },
          "country": {
            "description": "Country.",
            "type": "string"
          },
          "door": {
            "description": "Door or apartment identifier.",
            "type": "string"
          },
          "floor": {
            "description": "Floor.",
            "type": "string"
          },
          "housenumber": {
            "description": "House number.",
            "type": "string"
          },
          "infos": {
            "description": "Extra address information.",
            "type": "string"
          },
          "pollingstation": {
            "description": "Polling station.",
            "type": "string"
          },
          "postalcode": {
            "description": "Postal code.",
            "type": "string"
          },
          "state": {
            "description": "State or region.",
            "type": "string"
          },
          "street": {
            "description": "Street name.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContactUpsertData": {
        "additionalProperties": false,
        "properties": {
          "actions": {
            "description": "Task values by form ID or label.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertSelection"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "address": {
            "$ref": "#/components/schemas/ContactUpsertAddress",
            "description": "Postal address."
          },
          "age_category": {
            "description": "Internal age-category identifier.",
            "format": "int64",
            "type": "integer"
          },
          "birthcity": {
            "description": "Birth city.",
            "type": "string"
          },
          "birthcountry": {
            "description": "Birth country.",
            "type": "string"
          },
          "birthdate": {
            "description": "Birthdate in RFC3339 format.",
            "examples": [
              "1999-12-31T23:00:00.000Z"
            ],
            "format": "date-time",
            "type": "string"
          },
          "birthdept": {
            "description": "Birth department.",
            "type": "string"
          },
          "black_list": {
            "description": "Whether the contact is blacklisted.",
            "type": "boolean"
          },
          "consents": {
            "description": "Consent values by form ID or label.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertSelection"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "custom_fields": {
            "description": "Custom field values by form ID or label.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertSelection"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "firstname": {
            "description": "First name.",
            "examples": [
              "Jane"
            ],
            "type": "string"
          },
          "forms": {
            "description": "Survey values by form ID or label.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertSelection"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "gender": {
            "description": "Gender.",
            "enum": [
              "M",
              "F",
              "O"
            ],
            "examples": [
              "F"
            ],
            "type": "string"
          },
          "id": {
            "description": "Existing contact ID to update.",
            "examples": [
              42
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "mail": {
            "description": "Email address.",
            "examples": [
              "jane@example.com"
            ],
            "format": "email",
            "type": "string"
          },
          "married_name": {
            "description": "Married name.",
            "examples": [
              "Smith"
            ],
            "type": "string"
          },
          "mobile": {
            "description": "Mobile phone number.",
            "type": "string"
          },
          "name_presences": {
            "description": "Presence-status values by form ID or label.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertSelection"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "nationality": {
            "description": "Nationality.",
            "type": "string"
          },
          "nationbuilderid": {
            "description": "Legacy NationBuilder identifier.",
            "format": "int64",
            "type": "integer"
          },
          "notes": {
            "description": "Notes to attach to the contact.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertNote"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "phone": {
            "description": "Landline phone number.",
            "type": "string"
          },
          "status": {
            "description": "Level-of-support values by form ID or label.",
            "items": {
              "$ref": "#/components/schemas/ContactUpsertSelection"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "surname": {
            "description": "Last name.",
            "examples": [
              "Doe"
            ],
            "type": "string"
          },
          "tags": {
            "description": "Tags attached to the contact.",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "ContactUpsertNote": {
        "additionalProperties": false,
        "properties": {
          "content": {
            "description": "Note content.",
            "type": "string"
          },
          "id": {
            "description": "Existing note ID to update.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "pinned": {
            "description": "Whether the note is pinned.",
            "type": "boolean"
          }
        },
        "required": [
          "content"
        ],
        "type": "object"
      },
      "ContactUpsertSelection": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "description": "Form or refvalue ID.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "label": {
            "description": "Form or refvalue label.",
            "type": "string"
          },
          "value": {
            "description": "Submitted value.",
            "type": "string"
          }
        },
        "type": "object"
      },
      "CustomField": {
        "additionalProperties": false,
        "properties": {
          "data": {
            "description": "Custom field value.",
            "examples": [
              "XL"
            ],
            "type": "string"
          },
          "form_id": {
            "description": "Form ID.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "form_ref_id": {
            "description": "Form reference ID.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "id": {
            "description": "Custom field definition ID.",
            "format": "int64",
            "minimum": 0,
            "readOnly": true,
            "type": "integer"
          }
        },
        "required": [
          "id",
          "form_id",
          "form_ref_id",
          "data"
        ],
        "type": "object"
      },
      "Donation": {
        "additionalProperties": false,
        "properties": {
          "affectation": {
            "description": "Optional affectation code.",
            "type": "string"
          },
          "amount": {
            "description": "Amount in cents.",
            "examples": [
              2500
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "amount_initial": {
            "description": "Initial amount in cents.",
            "examples": [
              2500
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "comment": {
            "description": "Optional comment.",
            "type": "string"
          },
          "contact": {
            "$ref": "#/components/schemas/ContactForTransaction",
            "description": "Associated contact."
          },
          "contact_id": {
            "description": "Contact identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "ISO currency code.",
            "examples": [
              "EUR"
            ],
            "type": "string"
          },
          "date": {
            "description": "Donation date.",
            "format": "date-time",
            "type": "string"
          },
          "donation_price_id": {
            "description": "Donation price identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "transaction_bundle_id": {
            "description": "Bundle identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "amount",
          "currency",
          "amount_initial",
          "date",
          "contact_id",
          "transaction_bundle_id",
          "donation_price_id"
        ],
        "type": "object"
      },
      "DonationPrice": {
        "additionalProperties": false,
        "properties": {
          "allow_custom_amount": {
            "description": "Whether users can set a custom amount.",
            "type": "boolean"
          },
          "amount": {
            "description": "Amount in cents.",
            "examples": [
              1000
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "ISO currency code.",
            "examples": [
              "EUR"
            ],
            "type": "string"
          },
          "external_price_id": {
            "description": "External provider price identifier.",
            "type": "string"
          },
          "givexpert_template_id": {
            "description": "Givexpert template identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "hidden": {
            "description": "Whether this price is hidden.",
            "type": "boolean"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "kind": {
            "description": "Price kind.",
            "type": "string"
          },
          "name": {
            "description": "Price label.",
            "type": "string"
          },
          "rgive_price_id": {
            "description": "Rgive price identifier.",
            "type": "string"
          },
          "site_id": {
            "description": "Linked site identifier.",
            "type": "string"
          },
          "stripe_price_id": {
            "description": "Stripe price identifier.",
            "type": "string"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "amount",
          "currency",
          "allow_custom_amount",
          "name",
          "hidden"
        ],
        "type": "object"
      },
      "ErrorDetail": {
        "additionalProperties": false,
        "properties": {
          "location": {
            "description": "Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'",
            "type": "string"
          },
          "message": {
            "description": "Error message text",
            "type": "string"
          },
          "value": {
            "description": "The value at the given location"
          }
        },
        "type": "object"
      },
      "ErrorModel": {
        "additionalProperties": false,
        "properties": {
          "detail": {
            "description": "A human-readable explanation specific to this occurrence of the problem.",
            "examples": [
              "Property foo is required but is missing."
            ],
            "type": "string"
          },
          "errors": {
            "description": "Optional list of individual error details",
            "items": {
              "$ref": "#/components/schemas/ErrorDetail"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "instance": {
            "description": "A URI reference that identifies the specific occurrence of the problem.",
            "examples": [
              "https://example.com/error-log/abc123"
            ],
            "format": "uri",
            "type": "string"
          },
          "status": {
            "description": "HTTP status code",
            "examples": [
              400
            ],
            "format": "int64",
            "type": "integer"
          },
          "title": {
            "description": "A short, human-readable summary of the problem type. This value should not change between occurrences of the error.",
            "examples": [
              "Bad Request"
            ],
            "type": "string"
          },
          "type": {
            "default": "about:blank",
            "description": "A URI reference to human-readable documentation for the error.",
            "examples": [
              "https://example.com/errors/example"
            ],
            "format": "uri",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Form": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "description": "Unique identifier of the form.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "label": {
            "description": "Label of the form.",
            "examples": [
              "Volunteer registration"
            ],
            "type": "string"
          },
          "name": {
            "description": "Category of the form.",
            "enum": [
              "consent",
              "level_of_support",
              "presence_status",
              "custom_fields",
              "survey",
              "tasks"
            ],
            "examples": [
              "consent"
            ],
            "type": "string"
          },
          "refvalues": {
            "description": "A list of possible answers or predefined values associated with the form. These can be simple options or a range of values, depending on the form type.",
            "items": {
              "$ref": "#/components/schemas/Refvalue"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "type": {
            "description": "The format of the form.",
            "enum": [
              "radio",
              "text",
              "checkbox",
              "numeric",
              "date",
              "range",
              "photos",
              "signature",
              "qr_code"
            ],
            "examples": [
              "radio"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "name",
          "type",
          "refvalues"
        ],
        "type": "object"
      },
      "FormData": {
        "additionalProperties": false,
        "properties": {
          "data": {
            "description": "Form data value.",
            "examples": [
              "Some answer"
            ],
            "type": "string"
          },
          "date": {
            "description": "Date of the form data.",
            "format": "date-time",
            "type": "string"
          },
          "form_id": {
            "description": "Form ID.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "form_ref_id": {
            "description": "Form reference ID.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "id": {
            "description": "Form data ID.",
            "format": "int64",
            "minimum": 0,
            "readOnly": true,
            "type": "integer"
          },
          "survey_id": {
            "description": "Survey ID if the form data is from a survey.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "id",
          "form_id",
          "form_ref_id",
          "data"
        ],
        "type": "object"
      },
      "KpiContactsResponse": {
        "additionalProperties": false,
        "properties": {
          "total": {
            "description": "Total number of contacts matching the query.",
            "examples": [
              1597
            ],
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "total"
        ],
        "type": "object"
      },
      "ListResponseCodeCampaign": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "List of matching items.",
            "items": {
              "$ref": "#/components/schemas/CodeCampaign"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total number of matching items.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "type": "object"
      },
      "ListResponseDonationPrice": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "List of matching items.",
            "items": {
              "$ref": "#/components/schemas/DonationPrice"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total number of matching items.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "type": "object"
      },
      "ListResponseMembershipPrice": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "List of matching items.",
            "items": {
              "$ref": "#/components/schemas/MembershipPrice"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total number of matching items.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "type": "object"
      },
      "ListResponseMembershipPriceGroup": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "List of matching items.",
            "items": {
              "$ref": "#/components/schemas/MembershipPriceGroup"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total number of matching items.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "type": "object"
      },
      "ListResponseTransactionBundle": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "List of matching items.",
            "items": {
              "$ref": "#/components/schemas/TransactionBundle"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total number of matching items.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "type": "object"
      },
      "ListResponseTransactionStatus": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "List of matching items.",
            "items": {
              "$ref": "#/components/schemas/TransactionStatus"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "total": {
            "description": "Total number of matching items.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "type": "object"
      },
      "Membership": {
        "additionalProperties": false,
        "properties": {
          "amount": {
            "description": "Amount in cents.",
            "examples": [
              3000
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "amount_initial": {
            "description": "Initial amount in cents.",
            "examples": [
              3000
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "comment": {
            "description": "Optional comment.",
            "type": "string"
          },
          "contact": {
            "$ref": "#/components/schemas/ContactForTransaction",
            "description": "Associated contact."
          },
          "contact_id": {
            "description": "Contact identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "ISO currency code.",
            "examples": [
              "EUR"
            ],
            "type": "string"
          },
          "end_date": {
            "description": "Membership end date.",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "membership_price_id": {
            "description": "Membership price identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "rolling_year": {
            "description": "Rolling-year flag.",
            "type": "boolean"
          },
          "start_date": {
            "description": "Membership start date.",
            "format": "date-time",
            "type": "string"
          },
          "transaction_bundle_id": {
            "description": "Bundle identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "amount",
          "currency",
          "amount_initial",
          "contact_id",
          "start_date",
          "end_date",
          "transaction_bundle_id",
          "membership_price_id"
        ],
        "type": "object"
      },
      "MembershipPrice": {
        "additionalProperties": false,
        "properties": {
          "allow_custom_amount": {
            "description": "Whether users can set a custom amount.",
            "type": "boolean"
          },
          "amount": {
            "description": "Amount in cents.",
            "examples": [
              2000
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "ISO currency code.",
            "examples": [
              "EUR"
            ],
            "type": "string"
          },
          "duration": {
            "description": "Membership duration.",
            "type": "string"
          },
          "external_price_id": {
            "description": "External provider price identifier.",
            "type": "string"
          },
          "givexpert_item_code": {
            "description": "Givexpert item code.",
            "type": "string"
          },
          "hidden": {
            "description": "Whether this price is hidden.",
            "type": "boolean"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "kind": {
            "description": "Price kind.",
            "type": "string"
          },
          "membership_price_group_id": {
            "description": "Membership price group identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "name": {
            "description": "Price label.",
            "type": "string"
          },
          "rgive_price_id": {
            "description": "Rgive price identifier.",
            "type": "string"
          },
          "rolling_period": {
            "description": "Rolling period.",
            "type": "string"
          },
          "rolling_year": {
            "description": "Deprecated rolling-year flag.",
            "type": "boolean"
          },
          "site_id": {
            "description": "Linked site identifier.",
            "type": "string"
          },
          "stripe_price_id": {
            "description": "Stripe price identifier.",
            "type": "string"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "amount",
          "currency",
          "allow_custom_amount",
          "name",
          "hidden",
          "membership_price_group_id"
        ],
        "type": "object"
      },
      "MembershipPriceGroup": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "hidden": {
            "description": "Whether this group is hidden.",
            "type": "boolean"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "membership_prices": {
            "description": "Membership prices belonging to this group.",
            "items": {
              "$ref": "#/components/schemas/MembershipPrice"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "name": {
            "description": "Group label.",
            "type": "string"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "name",
          "hidden"
        ],
        "type": "object"
      },
      "Refvalue": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "description": "Unique identifier of the refvalue.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "label": {
            "description": "Label of the refvalue.",
            "examples": [
              "Yes"
            ],
            "type": "string"
          },
          "max": {
            "description": "Maximum value for numeric or range forms.",
            "examples": [
              5
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "min": {
            "description": "Minimum value for numeric or range forms.",
            "examples": [
              1
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "order": {
            "description": "The order in which the refvalues should be displayed for selection.",
            "examples": [
              1
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "step": {
            "description": "Step value for numeric or range forms, indicating the increments between valid values.",
            "examples": [
              1
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "value": {
            "description": "The actual value associated with the refvalue. This is what gets stored when the form is submitted.",
            "examples": [
              "yes"
            ],
            "type": "string"
          }
        },
        "required": [
          "id",
          "label",
          "value"
        ],
        "type": "object"
      },
      "Search": {
        "additionalProperties": false,
        "properties": {
          "advanced_search": {
            "$ref": "#/components/schemas/AdvancedSearch",
            "description": "Search parameters with filter query tree (see AdvancedSearchQuery for mutually exclusive options)."
          },
          "include_interactions": {
            "description": "Include interaction in results.",
            "examples": [
              true
            ],
            "type": "boolean"
          }
        },
        "required": [
          "advanced_search"
        ],
        "type": "object"
      },
      "SearchConditionGroup": {
        "oneOf": [
          {
            "additionalProperties": false,
            "description": "Every group/condition must be satisfied.",
            "properties": {
              "$all": {
                "description": "Individual filter conditions.",
                "items": {
                  "$ref": "#/components/schemas/AdvancedSearchCondition"
                },
                "type": "array"
              }
            },
            "required": [
              "$all"
            ],
            "title": "Match all (AND)",
            "type": "object"
          },
          {
            "additionalProperties": false,
            "description": "At least one group/condition must be satisfied.",
            "properties": {
              "$at_least_one": {
                "description": "Individual filter conditions.",
                "items": {
                  "$ref": "#/components/schemas/AdvancedSearchCondition"
                },
                "type": "array"
              }
            },
            "required": [
              "$at_least_one"
            ],
            "title": "Match at least one (OR)",
            "type": "object"
          }
        ]
      },
      "SearchContactsResponse": {
        "additionalProperties": false,
        "properties": {
          "contacts": {
            "description": "Matched contacts.",
            "items": {
              "$ref": "#/components/schemas/Contact"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "contacts"
        ],
        "type": "object"
      },
      "SuccessResponse": {
        "additionalProperties": false,
        "properties": {
          "message": {
            "description": "Human-readable success message.",
            "examples": [
              "Request accepted"
            ],
            "type": "string"
          }
        },
        "required": [
          "message"
        ],
        "type": "object"
      },
      "Tag": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "description": "Tag label.",
            "examples": [
              "volunteer"
            ],
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "type": "object"
      },
      "Transaction": {
        "additionalProperties": false,
        "properties": {
          "amount": {
            "description": "Amount in cents.",
            "examples": [
              5000
            ],
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "batch": {
            "$ref": "#/components/schemas/Batch",
            "description": "Batch metadata."
          },
          "batch_id": {
            "description": "Batch identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "code_campaign": {
            "description": "Campaign code.",
            "type": "string"
          },
          "comment": {
            "description": "Comment attached to status.",
            "type": "string"
          },
          "comment_date": {
            "description": "Comment timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "comment_user_id": {
            "description": "Comment author identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "contact": {
            "$ref": "#/components/schemas/ContactForTransaction",
            "description": "Associated contact."
          },
          "contact_id": {
            "description": "Contact identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "ISO currency code.",
            "examples": [
              "EUR"
            ],
            "type": "string"
          },
          "date": {
            "description": "Transaction date.",
            "format": "date-time",
            "type": "string"
          },
          "delivered_at": {
            "description": "Delivery date.",
            "format": "date-time",
            "type": "string"
          },
          "delivery_token": {
            "description": "Delivery token.",
            "type": "string"
          },
          "external_transaction_id": {
            "description": "External transaction identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "motif": {
            "$ref": "#/components/schemas/TransactionStatusCommentMotif",
            "description": "Associated status comment motif."
          },
          "motif_id": {
            "description": "Comment motif identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "payment_method": {
            "contentEncoding": "base64",
            "description": "Payment method payload.",
            "type": "string"
          },
          "payment_method_kind": {
            "description": "Payment method kind.",
            "type": "string"
          },
          "reimbursed_amount": {
            "description": "Reimbursed amount in cents.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "status_id": {
            "description": "Transaction status identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "transaction_bundle_id": {
            "description": "Bundle identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "unpaid_amount": {
            "description": "Unpaid amount in cents.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/UserForTransaction",
            "description": "Associated user."
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "payment_method_kind",
          "contact_id",
          "transaction_bundle_id",
          "amount",
          "currency",
          "status_id",
          "reimbursed_amount",
          "unpaid_amount"
        ],
        "type": "object"
      },
      "TransactionBundle": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "donations": {
            "description": "Donations in this bundle.",
            "items": {
              "$ref": "#/components/schemas/Donation"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "memberships": {
            "description": "Memberships in this bundle.",
            "items": {
              "$ref": "#/components/schemas/Membership"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "summary": {
            "contentEncoding": "base64",
            "description": "Bundle summary payload.",
            "type": "string"
          },
          "transactions": {
            "description": "Transactions in this bundle.",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at"
        ],
        "type": "object"
      },
      "TransactionBundleHistoryEntry": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "kind": {
            "description": "Updated entity kind.",
            "type": "string"
          },
          "new": {
            "contentEncoding": "base64",
            "description": "New values snapshot.",
            "type": "string"
          },
          "old": {
            "contentEncoding": "base64",
            "description": "Previous values snapshot.",
            "type": "string"
          },
          "source": {
            "contentEncoding": "base64",
            "description": "Source metadata.",
            "type": "string"
          },
          "target_id": {
            "description": "Target record identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "transaction_bundle_id": {
            "description": "Transaction bundle identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "user": {
            "$ref": "#/components/schemas/UserForTransaction",
            "description": "User responsible for the change."
          }
        },
        "required": [
          "id",
          "created_at",
          "transaction_bundle_id",
          "target_id",
          "kind",
          "user"
        ],
        "type": "object"
      },
      "TransactionSettings": {
        "additionalProperties": false,
        "properties": {
          "additional_settings": {
            "contentEncoding": "base64",
            "description": "Additional settings payload.",
            "type": "string"
          },
          "batch_prefix": {
            "description": "Prefix used for batch references.",
            "type": "string"
          },
          "batch_serial": {
            "description": "Current batch serial.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "batch_serial_updated_at": {
            "description": "Batch serial last update time.",
            "format": "date-time",
            "type": "string"
          },
          "currency": {
            "description": "Default currency.",
            "examples": [
              "EUR"
            ],
            "type": "string"
          },
          "default_donation_price_id": {
            "description": "Default donation price identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "default_membership_price_id": {
            "description": "Default membership price identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "default_status_id": {
            "description": "Default transaction status identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "max_batch_size": {
            "description": "Maximum number of transactions per batch.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "membership_prefix": {
            "description": "Membership prefix.",
            "type": "string"
          },
          "membership_serial": {
            "description": "Current membership serial.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "open_periods": {
            "contentEncoding": "base64",
            "description": "Membership open periods configuration.",
            "type": "string"
          },
          "payment_method_kinds": {
            "description": "Enabled payment methods.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "payment_method_kinds",
          "max_batch_size",
          "default_status_id",
          "default_membership_price_id",
          "default_donation_price_id",
          "batch_prefix",
          "batch_serial_updated_at",
          "batch_serial",
          "membership_serial",
          "membership_prefix",
          "currency"
        ],
        "type": "object"
      },
      "TransactionStatus": {
        "additionalProperties": false,
        "properties": {
          "archived": {
            "description": "Whether the status is archived.",
            "type": "boolean"
          },
          "color": {
            "description": "Status color.",
            "type": "string"
          },
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "kind": {
            "description": "Status category.",
            "type": "string"
          },
          "name": {
            "description": "Status name.",
            "type": "string"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "name",
          "color",
          "kind",
          "archived"
        ],
        "type": "object"
      },
      "TransactionStatusCommentMotif": {
        "additionalProperties": false,
        "properties": {
          "created_at": {
            "description": "Creation timestamp.",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "label": {
            "description": "Motif label.",
            "type": "string"
          },
          "transaction_status_id": {
            "description": "Transaction status identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "updated_at": {
            "description": "Last update timestamp.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at",
          "transaction_status_id",
          "label"
        ],
        "type": "object"
      },
      "UserForTransaction": {
        "additionalProperties": false,
        "properties": {
          "avatar": {
            "description": "Avatar URL.",
            "type": "string"
          },
          "firstname": {
            "description": "User first name.",
            "type": "string"
          },
          "id": {
            "description": "Unique identifier.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "role": {
            "description": "Role label.",
            "type": "string"
          },
          "surname": {
            "description": "User surname.",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "bearerFormat": "opaque",
        "description": "Access token required to authenticate requests. Obtain a token through the Settings page in your Qomon account.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "This documentation provides a comprehensive reference for the Qomon API, which allows you to manage contacts, forms, searches, and transactions within the Qomon platform. The API is designed to be RESTful and follows standard HTTP conventions for authentication, rate limiting, and error handling.",
    "title": "Qomon API Reference",
    "version": ""
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/code-campaigns": {
      "get": {
        "description": "Returns paginated code campaigns.",
        "operationId": "list-code-campaigns",
        "parameters": [
          {
            "description": "Maximum number of items to return.",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 20,
              "description": "Maximum number of items to return.",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Number of items to skip.",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Number of items to skip.",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponseCodeCampaign"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List code campaigns",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/contacts": {
      "post": {
        "description": "Creates one contact synchronously in the Qomon database.\n\nFor mass synchronization and updates, prefer `/contacts/upsert`.",
        "operationId": "create-contact",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Contact"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a contact (synchronous)",
        "tags": [
          "Contacts"
        ]
      }
    },
    "/v1/contacts/upsert": {
      "post": {
        "description": "Publishes a contact upsert job to RabbitMQ using the legacy asynchronous contract. The API returns `202 Accepted` once the message has been handed to the broker.",
        "operationId": "upsert-contact",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactUpsertData"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            },
            "description": "Accepted"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Upsert a contact asynchronously",
        "tags": [
          "Contacts"
        ]
      }
    },
    "/v1/contacts/{id}": {
      "delete": {
        "description": "Permanently deletes a contact by ID. This also removes the contact from the search index and unlinks any associated facts.",
        "operationId": "delete-contact",
        "parameters": [
          {
            "description": "Contact ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Contact ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a contact by ID",
        "tags": [
          "Contacts"
        ]
      },
      "get": {
        "description": "Returns a single contact by ID.\n\nIn the response, advanced fields (consents, surveys, level of support, etc.) are formatted as `formdatas` with `form_id` and `form_ref_id` references. Use the `/forms/{id}` endpoint to decode these references and interpret their values.",
        "operationId": "get-contact",
        "parameters": [
          {
            "description": "Contact ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Contact ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Find a contact by ID",
        "tags": [
          "Contacts"
        ]
      },
      "patch": {
        "description": "Partially updates an existing contact by ID in the Qomon database.\n\nFor mass updates or upserting contacts, consider using the `/contacts/upsert` endpoint instead.\n\nTo set advanced fields (custom fields, surveys, consents, level of support, etc.), use the `formdatas` array with:\n- `form_id`: The ID of the advanced field\n- `form_ref_id`: The ID of the value/option for that field",
        "operationId": "update-contact",
        "parameters": [
          {
            "description": "Contact ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Contact ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Contact"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Update an existing contact by ID (synchronous)",
        "tags": [
          "Contacts"
        ]
      }
    },
    "/v1/donation-prices": {
      "get": {
        "description": "Returns paginated donation prices.",
        "operationId": "list-donation-prices",
        "parameters": [
          {
            "description": "Maximum number of items to return.",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 20,
              "description": "Maximum number of items to return.",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Number of items to skip.",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Number of items to skip.",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponseDonationPrice"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List donation prices",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/forms/type/{type}": {
      "get": {
        "description": "Returns forms for a specific type. Allowed values: consent, survey, level_of_support, custom_fields, presence_status, tasks.",
        "operationId": "list-forms-by-type",
        "parameters": [
          {
            "description": "Form type.",
            "in": "path",
            "name": "type",
            "required": true,
            "schema": {
              "description": "Form type.",
              "enum": [
                "consent",
                "survey",
                "level_of_support",
                "custom_fields",
                "presence_status",
                "tasks"
              ],
              "examples": [
                "consent"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/Form"
                  },
                  "type": [
                    "array",
                    "null"
                  ]
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List forms by type",
        "tags": [
          "Forms"
        ]
      }
    },
    "/v1/forms/{id}": {
      "get": {
        "description": "Returns a single form by ID.",
        "operationId": "get-form",
        "parameters": [
          {
            "description": "Form ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Form ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Form"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a form",
        "tags": [
          "Forms"
        ]
      }
    },
    "/v1/kpi": {
      "post": {
        "description": "Return KPI totals for contacts matching a query.",
        "operationId": "get-contacts-kpi",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "count-all": {
                  "summary": "Count all contacts",
                  "value": {
                    "advanced_search": {
                      "page": 0,
                      "per_page": 1,
                      "query": {
                        "$all": [
                          {
                            "$all": [
                              {
                                "attr": "Exists",
                                "ope": "ext"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                },
                "count-by-city": {
                  "summary": "Count contacts in a city",
                  "value": {
                    "advanced_search": {
                      "page": 0,
                      "per_page": 1,
                      "query": {
                        "$all": [
                          {
                            "$all": [
                              {
                                "attr": "city",
                                "ope": "eql",
                                "value": "Paris"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/Search"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KpiContactsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Contact count KPI",
        "tags": [
          "Search"
        ]
      }
    },
    "/v1/membership-price-groups": {
      "get": {
        "description": "Returns paginated membership price groups.",
        "operationId": "list-membership-price-groups",
        "parameters": [
          {
            "description": "Maximum number of items to return.",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 20,
              "description": "Maximum number of items to return.",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Number of items to skip.",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Number of items to skip.",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponseMembershipPriceGroup"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List membership price groups",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/membership-prices": {
      "get": {
        "description": "Returns paginated membership prices.",
        "operationId": "list-membership-prices",
        "parameters": [
          {
            "description": "Maximum number of items to return.",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 20,
              "description": "Maximum number of items to return.",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Number of items to skip.",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Number of items to skip.",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponseMembershipPrice"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List membership prices",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/search": {
      "post": {
        "description": "Search contacts matching a query.",
        "operationId": "search-contacts",
        "requestBody": {
          "content": {
            "application/json": {
              "examples": {
                "filter-by-city": {
                  "summary": "Filter contacts by city (AND)",
                  "value": {
                    "advanced_search": {
                      "page": 0,
                      "per_page": 50,
                      "query": {
                        "$all": [
                          {
                            "$all": [
                              {
                                "attr": "city",
                                "ope": "eql",
                                "value": "Paris"
                              }
                            ]
                          }
                        ]
                      },
                      "sort_asc": true,
                      "sort_attr": "surname"
                    }
                  }
                },
                "multiple-or-groups": {
                  "summary": "Match any of several groups (OR)",
                  "value": {
                    "advanced_search": {
                      "page": 0,
                      "per_page": 50,
                      "query": {
                        "$at_least_one": [
                          {
                            "$all": [
                              {
                                "attr": "gender",
                                "ope": "eql",
                                "value": "F"
                              }
                            ]
                          },
                          {
                            "$all": [
                              {
                                "attr": "city",
                                "ope": "eql",
                                "value": "Paris"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                },
                "recently-updated": {
                  "summary": "Contacts updated in the last 24 hours",
                  "value": {
                    "advanced_search": {
                      "page": 0,
                      "per_page": 100,
                      "query": {
                        "$all": [
                          {
                            "$all": [
                              {
                                "attr": "UpdatedAt",
                                "ope": "gte",
                                "value": "now-1d/d"
                              }
                            ]
                          }
                        ]
                      }
                    }
                  }
                }
              },
              "schema": {
                "$ref": "#/components/schemas/Search"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchContactsResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Search contacts",
        "tags": [
          "Search"
        ]
      }
    },
    "/v1/transaction-bundles": {
      "get": {
        "description": "Returns paginated transaction bundles.",
        "operationId": "list-transaction-bundles",
        "parameters": [
          {
            "description": "Maximum number of items to return.",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 20,
              "description": "Maximum number of items to return.",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Number of items to skip.",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Number of items to skip.",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponseTransactionBundle"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List transaction bundles",
        "tags": [
          "Transactions"
        ]
      },
      "post": {
        "description": "Creates a transaction bundle with related transactions, memberships, and donations.",
        "operationId": "create-transaction-bundle",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionBundle"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionBundle"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Create a transaction bundle",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/transaction-bundles/{id}": {
      "delete": {
        "description": "Deletes a transaction bundle by ID.",
        "operationId": "delete-transaction-bundle",
        "parameters": [
          {
            "description": "Transaction bundle ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Transaction bundle ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Delete a transaction bundle",
        "tags": [
          "Transactions"
        ]
      },
      "get": {
        "description": "Returns a single transaction bundle by ID.",
        "operationId": "get-transaction-bundle",
        "parameters": [
          {
            "description": "Transaction bundle ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Transaction bundle ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionBundle"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get a transaction bundle",
        "tags": [
          "Transactions"
        ]
      },
      "patch": {
        "description": "Partially updates a transaction bundle by ID.",
        "operationId": "update-transaction-bundle",
        "parameters": [
          {
            "description": "Transaction bundle ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Transaction bundle ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionBundle"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionBundle"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Update a transaction bundle",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/transaction-bundles/{id}/history": {
      "get": {
        "description": "Returns history entries for a transaction bundle.",
        "operationId": "list-transaction-bundle-history",
        "parameters": [
          {
            "description": "Transaction bundle ID.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "description": "Transaction bundle ID.",
              "examples": [
                42
              ],
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/TransactionBundleHistoryEntry"
                  },
                  "type": [
                    "array",
                    "null"
                  ]
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List transaction bundle history",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/transaction-settings": {
      "get": {
        "description": "Returns transaction settings for the authenticated group.",
        "operationId": "get-transaction-settings",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionSettings"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "Get transaction settings",
        "tags": [
          "Transactions"
        ]
      }
    },
    "/v1/transaction-statuses": {
      "get": {
        "description": "Returns paginated transaction statuses.",
        "operationId": "list-transaction-statuses",
        "parameters": [
          {
            "description": "Maximum number of items to return.",
            "explode": false,
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 20,
              "description": "Maximum number of items to return.",
              "format": "int64",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Number of items to skip.",
            "explode": false,
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "description": "Number of items to skip.",
              "format": "int64",
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponseTransactionStatus"
                }
              }
            },
            "description": "OK"
          },
          "default": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            },
            "description": "Error"
          }
        },
        "summary": "List transaction statuses",
        "tags": [
          "Transactions"
        ]
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "servers": [
    {
      "description": "Local development server",
      "url": "http://localhost:8888"
    }
  ],
  "tags": [
    {
      "description": "All `/v1` endpoints require an access token in the `Authorization` header.\n\nUse the format: `Authorization: Bearer <token>`.\n\nObtain a token through the Settings page in your Qomon account.",
      "name": "Authentication"
    },
    {
      "description": "Rate limiting is enforced before request handling. When the limit is reached, the API returns `429 Too Many Requests`.\n\nEach response includes rate limit headers:\n- `X-RateLimit-Limit`\n- `X-RateLimit-Remaining`\n- `X-RateLimit-Reset`\n\nIf throttled, a `Retry-After` header is returned to indicate when the client can retry.",
      "name": "Rate Limiting"
    },
    {
      "description": "Create, read, update, and delete Qomon contacts.\n\n**Basic fields:** name, email, phone, address, tags, gender, birthdate, etc.\n\n**Advanced fields:** consents, surveys, custom fields, level of support, tasks.\n\n**Operations:**\n- `/contacts/upsert` (async) — Recommended for synchronizing and mass-updating contacts\n- `/contacts` (sync) — Create individual contacts\n- `/contacts/{id}` (sync) — Read, update, or delete individual contacts",
      "name": "Contacts"
    },
    {
      "description": "Retrieve form definitions and their possible values (refvalues).\n\n**Use forms to:**\n- Understand and interpret contact advanced fields\n- Look up valid values for consents, surveys, custom fields, task assignments\n- Explore available form types and their structure\n\n**Form types:** consent, level_of_support, presence_status, custom_fields, survey, tasks",
      "name": "Forms"
    },
    {
      "description": "Search contacts and retrieve aggregate KPI totals based on advanced filters.",
      "name": "Search"
    },
    {
      "description": "Manage transaction bundles and list transaction configuration resources (statuses, prices, settings, and code campaigns).",
      "name": "Transactions"
    },
    {
      "description": "If you are building an integration to keep your external database or CRM synchronized with Qomon, you will need a reliable way to fetch recently updated contacts records.\n\n## The Endpoint\n\n**HTTP Method:** `POST`\n\n**Endpoint:** `/v1/search`\n\n```json\n{\n  \"data\": {\n    \"advanced_search\": {\n      \"page\": 0,\n      \"per_page\": 100,\n      \"query\": {\n        \"$all\": [{ \"$all\": [{ \"$condition\": {\n          \"attr\": \"UpdatedAt\",\n          \"ope\": \"gte\",\n          \"value\": \"now-1d/d\"\n        }}]}]\n      }\n    }\n  }\n}\n```\n\n## Understanding the Date Filter\n\n- **`attr: \"UpdatedAt\"`** — Targets the last-modified timestamp\n- **`ope: \"gte\"`** — Greater Than or Equal\n- **`value: \"now-1d/d\"`** — Now minus 1 day, rounded to start of day\n\n## Handling Pagination\n\n1. Start with `\"page\": 0`\n2. Process the returned contacts\n3. If the array has 1000 items, increment page and repeat\n4. Stop when fewer than 1000 items are returned",
      "name": "API Polling"
    }
  ]
}