openapi: 3.0.3 info: title: Bloomerang REST API v2 Constituents API description: The Bloomerang REST API v2 is a private-key, server-to-server API for reading and writing data in a Bloomerang donor management CRM account - constituents, transactions (donations, pledges, recurring donations), interactions, notes, relationships, and webhook subscriptions. Requests are authenticated with either a private API key sent in the X-Api-Key header (generated by an Administrator user under User Settings) or an OAuth 2.0 access token for third-party applications. Bloomerang does not offer a sandbox environment - all requests operate against production data. Endpoints for Constituents, Transactions, and Interactions are directly confirmed in Bloomerang's public documentation and third-party integration guides; endpoints for Households, Notes, Relationships, Custom Fields, Webhooks, Users, Funds, Campaigns, and Appeals are modeled from Bloomerang's REST API v1 resource parity, community client libraries, and CRM feature documentation, since Bloomerang does not publish a complete, versioned OpenAPI/Swagger document for v2. See review.yml in this repository for the endpointsConfirmed vs endpointsModeled breakdown. version: '2.0' contact: name: Bloomerang url: https://bloomerang.com/api/rest-api servers: - url: https://api.bloomerang.co/v2 description: Bloomerang REST API v2 (production - no sandbox is offered) security: - apiKeyAuth: [] - oauth2Bearer: [] tags: - name: Constituents description: Individuals, households, and organizations tracked as donors and contacts. paths: /constituents: get: operationId: listConstituents tags: - Constituents summary: List constituents description: Lists constituents, paginated with skip/take parameters. parameters: - $ref: '#/components/parameters/Skip' - $ref: '#/components/parameters/Take' responses: '200': description: A page of constituents. content: application/json: schema: type: object properties: Results: type: array items: $ref: '#/components/schemas/Constituent' Total: type: integer '401': $ref: '#/components/responses/Unauthorized' post: operationId: createConstituent tags: - Constituents summary: Create a constituent description: Creates a new constituent record. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ConstituentInput' responses: '200': description: The created constituent. content: application/json: schema: $ref: '#/components/schemas/Constituent' '401': $ref: '#/components/responses/Unauthorized' '422': $ref: '#/components/responses/ValidationError' /constituents/search: get: operationId: searchConstituents tags: - Constituents summary: Search constituents description: Full-text search across constituent names and identifying fields. parameters: - name: search in: query required: true description: Search term, e.g. a constituent's name. schema: type: string - $ref: '#/components/parameters/Skip' - $ref: '#/components/parameters/Take' responses: '200': description: Matching constituents. content: application/json: schema: type: object properties: Results: type: array items: $ref: '#/components/schemas/Constituent' '401': $ref: '#/components/responses/Unauthorized' /constituents/{id}: parameters: - $ref: '#/components/parameters/ConstituentId' get: operationId: getConstituent tags: - Constituents summary: Retrieve a constituent description: Retrieves a constituent by ID. responses: '200': description: The requested constituent. content: application/json: schema: $ref: '#/components/schemas/Constituent' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: operationId: updateConstituent tags: - Constituents summary: Update a constituent description: Updates fields on an existing constituent. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ConstituentInput' responses: '200': description: The updated constituent. content: application/json: schema: $ref: '#/components/schemas/Constituent' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '422': $ref: '#/components/responses/ValidationError' /constituents/{id}/timeline: parameters: - $ref: '#/components/parameters/ConstituentId' get: operationId: getConstituentTimeline tags: - Constituents summary: Get a constituent's timeline description: Retrieves the combined engagement timeline for a constituent - notes, interactions, donations, recurring donations, recurring donation payments, pledges, pledge payments, and tasks. responses: '200': description: The constituent timeline. content: application/json: schema: $ref: '#/components/schemas/ConstituentTimeline' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' components: schemas: Note: allOf: - $ref: '#/components/schemas/NoteInput' - type: object properties: Id: type: integer ConstituentTimeline: type: object properties: Id: type: integer Notes: type: array items: $ref: '#/components/schemas/Note' Interactions: type: array items: $ref: '#/components/schemas/Interaction' Donations: type: array items: $ref: '#/components/schemas/Transaction' RecurringDonations: type: array items: type: object additionalProperties: true RecurringDonationPayments: type: array items: type: object additionalProperties: true Pledges: type: array items: type: object additionalProperties: true PledgePayments: type: array items: type: object additionalProperties: true Tasks: type: array items: type: object additionalProperties: true Transaction: allOf: - $ref: '#/components/schemas/TransactionInput' - type: object properties: Id: type: integer CreatedDate: type: string format: date-time InteractionInput: type: object required: - AccountId - Date - Channel properties: AccountId: type: integer Date: type: string format: date Channel: type: string enum: - Call - Email - InPerson - Letter - Other Purpose: type: string Note: type: string UserId: type: integer Error: type: object properties: Message: type: string Errors: type: array items: type: string Constituent: allOf: - $ref: '#/components/schemas/ConstituentInput' - type: object properties: Id: type: integer AccountNumber: type: string CreatedDate: type: string format: date-time LastModifiedDate: type: string format: date-time NoteInput: type: object required: - AccountId - Note properties: AccountId: type: integer Note: type: string Date: type: string format: date AttachmentIds: type: array items: type: integer ConstituentInput: type: object properties: Type: type: string enum: - Individual - Organization - Household FirstName: type: string LastName: type: string FullName: type: string Status: type: string enum: - Active - Inactive - Deceased EmailAddress: type: object properties: Value: type: string format: email Type: type: string PhoneNumber: type: object properties: Number: type: string Type: type: string Address: type: object properties: Street: type: string City: type: string State: type: string PostalCode: type: string Country: type: string CustomValues: type: array items: type: object additionalProperties: true TransactionInput: type: object required: - AccountId - Date - Designations properties: AccountId: type: integer description: The constituent ID this transaction is attributed to. Date: type: string format: date Method: type: string enum: - Cash - Check - CreditCard - AchDebit - Other Designations: type: array items: type: object properties: Type: type: string enum: - Donation - Pledge - PledgePayment - RecurringDonation - RecurringDonationPayment FundId: type: integer CampaignId: type: integer AppealId: type: integer Amount: type: number format: double Interaction: allOf: - $ref: '#/components/schemas/InteractionInput' - type: object properties: Id: type: integer parameters: Skip: name: skip in: query required: false description: Number of records to skip, for pagination. schema: type: integer default: 0 Take: name: take in: query required: false description: Number of records to return, for pagination. schema: type: integer default: 50 ConstituentId: name: id in: path required: true description: The ID of the constituent. schema: type: integer responses: Unauthorized: description: Missing or invalid API key / access token. content: application/json: schema: $ref: '#/components/schemas/Error' ValidationError: description: The request payload failed validation. content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: The requested resource was not found. content: application/json: schema: $ref: '#/components/schemas/Error' securitySchemes: apiKeyAuth: type: apiKey in: header name: X-Api-Key description: Private API key generated by an Administrator user in Bloomerang under User Settings > Edit My User. Grants full read/write access - keep it secret. oauth2Bearer: type: oauth2 description: 'OAuth 2.0 access token for third-party applications, presented as `Authorization: Bearer {access_token}`.' flows: authorizationCode: authorizationUrl: https://crm.bloomerang.co/oauth/authorize tokenUrl: https://api.bloomerang.co/v2/oauth/token scopes: api: Full read/write access to account data.