---
swagger: '2.0'
info:
  version: 1.0.0
  title: GiveCampus Opportunities API
  description: |-
    The Opportunities API allows your school to send and retrieve opportunity data to GiveCampus in JSON format. <h2>Security</h2> <p>Every API request must have a bearer token attached in the Authorization header.</p> <p>These tokens are generated within the GiveCampus UI and only school administrators with super-user permissions can generate and manage them. You will choose this initial set of “full” administrators during the GiveCampus onboarding process.</p> <p>All API responses will be delivered over a secure HTTPS connection, and a TLS version of 1.2 or 1.3 is required.</p> <p>GiveCampus maintains detailed logs of API access and can provide them to your team upon request.</p> <h2>Request Lifecycle</h2> <p>The API delivers data asynchronously using a request-and-poll pattern:</p> <ol>
      <li><strong>Submit your request</strong> — Call the endpoint with your desired parameters. You'll receive a <code>request_id</code> and a <code>status</code> of <code>in_progress</code>.</li>
      <li><strong>Poll for results</strong> — Call <code>/results/{request_id}</code> every 2–5 seconds until <code>status</code> changes to <code>completed</code> (or <code>error</code>).</li>
      <li><strong>Download your data</strong> — When complete, the response includes a <code>download_url</code> containing a JSON array of objects matching the model defined below.</li>
    </ol> <p>Most requests complete within a few seconds.</p> <h2>Testing</h2> <p>You can use the tools below to see responses from the API to understand how to build your own implementation.</p> <p>You will see the URLs and paths necessary to make your own API calls.</p> <ol>
      <li>Click the Authorize button below to enter in your API Key in the following format: <code>Bearer API_TOKEN</code></li>
      <li>After authorized, you can click the close button in the authorization modal to start making requests</li>
      <li>Expand the Opportunities section below to see the available parameters that you can leverage to filter API results.</li>
      <li>After requesting a subset of opportunities, you will receive a <code>request_id</code>.  Copy that ID and then use that in the <code>results</code> section to see the progress of your request and to see the download URL once the request is completed.</li>
    </ol> <p>In the routes section below, there is a "Try it out" button.  After authenticating, you can select from the available parameters, and you will see the curl request performed, the results of your request, and any errors if applicable.</p> <p><i>GiveCampus Proprietary and Confidential</i></p>
basePath: "/api"
securityDefinitions:
  Bearer:
    type: apiKey
    name: Authorization
    in: header
    description: Enter the token with the `Bearer ` prefix, e.g. "Bearer XXXXXXXXXXXXX".
paths:
  "/opportunities/search":
    post:
      tags:
      - Opportunities
      summary: Search opportunities
      description: "<p>Search for opportunities based on various criteria. Returns
        a list of matching opportunities.</p> <p>ids (optional) -  Array of your external
        CRM’s identifier</p> <p>constituent_external_ids (optional) -  Array of your
        external CRM’s constituent identifier</p> <p>gift_officer_external_ids (optional)
        -  Array of your external CRM’s gift officer identifier</p> <p>opportunity_statuses
        (optional) -  Array of opportunity statuses</p> <p>opportunity_types (optional)
        -  Array of opportunity types</p> <p>created_at (optional) -  UTC Unix Timestamp
        of when opportunity was created; if provided, the API will return all records
        updated on or after this timestamp</p> <p>last_updated_at (optional) -  UTC
        Unix Timestamp of when opportunity was last modified; if provided, the API
        will return all records updated on or after this timestamp</p>"
      operationId: searchOpportunities
      consumes:
      - application/json
      produces:
      - application/json
      parameters:
      - in: body
        name: search_request
        required: true
        schema:
          type: object
          "$ref": "#/definitions/SearchOpportunity"
      security:
      - Bearer: []
      responses:
        '202':
          description: Submitted successfully. Returns a request ID.
          schema:
            "$ref": "#/definitions/ApiRequest"
        '400':
          description: Invalid request
          schema:
            "$ref": "../v2.0.0/types/bad_request_error.yaml"
        '401':
          description: Unauthorized
          schema:
            "$ref": "../v2.0.0/types/unauthorized_error.yaml"
        '500':
          description: Internal Server Error
          schema:
            "$ref": "../v2.0.0/types/internal_server_error.yaml"
  "/opportunities":
    post:
      tags:
      - Opportunities
      summary: Submit opportunities
      description: Submit one or more opportunities. Each opportunity must include
        required fields. Limited to 5000 records per request.
      operationId: createOpportunities
      consumes:
      - application/json
      produces:
      - application/json
      parameters:
      - in: body
        name: opportunities
        required: true
        schema:
          type: array
          items:
            "$ref": "#/definitions/CreateOpportunity"
      security:
      - Bearer: []
      responses:
        '202':
          description: Submitted successfully. Returns a request ID.
          schema:
            "$ref": "#/definitions/ApiRequest"
        '400':
          description: Invalid request
          schema:
            "$ref": "../v2.0.0/types/bad_request_error.yaml"
        '401':
          description: Unauthorized
          schema:
            "$ref": "../v2.0.0/types/unauthorized_error.yaml"
        '500':
          description: Internal Server Error
          schema:
            "$ref": "../v2.0.0/types/internal_server_error.yaml"
    put:
      tags:
      - Opportunities
      summary: Update opportunities
      description: Submit one or more opportunities. Each opportunity must include
        required fields. Limited to 5000 records per request.
      operationId: updateOpportunities
      consumes:
      - application/json
      produces:
      - application/json
      parameters:
      - in: body
        name: opportunities
        required: true
        schema:
          type: array
          items:
            "$ref": "#/definitions/UpdateOpportunity"
      security:
      - Bearer: []
      responses:
        '202':
          description: Submitted successfully. Returns a request ID.
          schema:
            "$ref": "#/definitions/ApiRequest"
        '400':
          description: Invalid request
          schema:
            "$ref": "../v2.0.0/types/bad_request_error.yaml"
        '401':
          description: Unauthorized
          schema:
            "$ref": "../v2.0.0/types/unauthorized_error.yaml"
        '500':
          description: Internal Server Error
          schema:
            "$ref": "../v2.0.0/types/internal_server_error.yaml"
  "/results/{request_id}":
    get:
      tags:
      - Results
      summary: Get processing results
      description: Returns status and download URL once the submitted opportunities
        have been processed.
      operationId: getOpportunityResults
      produces:
      - application/json
      parameters:
      - in: path
        name: request_id
        type: string
        required: true
        description: Request ID returned from submission
      security:
      - Bearer: []
      responses:
        '200':
          description: Status and download URL
          schema:
            "$ref": "#/definitions/ApiResults"
        '202':
          description: Status of your request
          schema:
            "$ref": "../shared/types/in_progress_api_results.yaml"
        '401':
          description: Unauthorized
          schema:
            "$ref": "../v2.0.0/types/unauthorized_error.yaml"
        '404':
          description: Not Found
          schema:
            "$ref": "../v2.0.0/types/not_found_error.yaml"
        '500':
          description: Internal Server Error
          schema:
            "$ref": "../v2.0.0/types/internal_server_error.yaml"
definitions:
  SearchOpportunity:
    type: object
    properties:
      ids:
        type: array
        items:
          type: string
        description: Filter by opportunity external IDs
      constituent_external_ids:
        type: array
        items:
          type: string
        description: Filter by constituent external IDs
      gift_officer_external_ids:
        type: array
        items:
          type: string
        description: Filter by gift officer external IDs
      opportunity_statuses:
        type: array
        items:
          type: string
        description: Filter by opportunity statuses (e.g., open, closed, won, lost)
      opportunity_types:
        type: array
        items:
          type: string
        description: Filter by opportunity types (e.g., major gift, planned gift,
          annual fund)
      created_at:
        type: integer
        description: Filter by opportunities created on or after this date (Unix timestamp
          in seconds)
      last_updated_at:
        type: integer
        description: Filter by opportunities last updated on or after this date (Unix
          timestamp in seconds)
  CreateOpportunity:
    type: object
    required:
    - external_id
    - primary_person_external_id
    - primary_gift_officer
    - opportunity_status_name
    - opportunity_type_name
    properties:
      external_id:
        type: string
        example: OPP-2023-001
      name:
        type: string
      notes:
        type: string
      opportunity_status_name:
        type: string
        description: Must match an existing status
      opportunity_type_name:
        type: string
        description: Must match an existing type
      opportunity_likelihood_name:
        type: string
        description: Must match an existing likelihood
      ask_date:
        type: integer
        description: Unix timestamp in seconds
      expected_response_date:
        type: integer
        description: Unix timestamp in seconds
      response_date:
        type: integer
        description: Unix timestamp in seconds
      ask_amount:
        type: number
        format: float
      accepted_amount:
        type: number
        format: float
      custom_amount_1:
        type: number
        format: float
      expected_close_date:
        type: integer
        description: Unix timestamp in seconds
      expected_ask_amount:
        type: number
        format: float
      expected_amount:
        type: number
        format: float
      expected_ask_date:
        type: integer
        description: Unix timestamp in seconds
      primary_person_external_id:
        type: string
      participant_people_external_ids:
        type: array
        items:
          type: string
      primary_gift_officer:
        type: object
        required:
        - external_id
        properties:
          external_id:
            type: string
          email:
            type: string
      secondary_gift_officers:
        type: array
        items:
          type: object
          properties:
            external_id:
              type: string
            email:
              type: string
      custom_field_boolean_values:
        type: array
        items:
          type: object
          properties:
            custom_field_label:
              type: string
              example: Interested in volunteering
            value:
              type: boolean
              example: true
      custom_field_selected_list_values:
        type: array
        items:
          type: object
          properties:
            custom_field_label:
              type: string
              example: Preferred contact method
            value:
              type: string
              example: Email
      custom_field_string_values:
        type: array
        items:
          type: object
          properties:
            custom_field_label:
              type: string
              example: Notes
            value:
              type: string
              example: Discussed upcoming events and fundraising goals
      opportunity_allocations:
        type: array
        items:
          type: object
          required:
          - opportunity_allocation_amounts
          - designation_id
          - external_id
          properties:
            external_id:
              type: string
            designation_id:
              type: integer
            opportunity_allocation_amounts:
              type: array
              items:
                type: object
                required:
                - amount_type_name
                - amount
                properties:
                  amount_type_name:
                    type: string
                  amount:
                    type: number
                    format: float
            custom_field_string_values:
              type: array
              items:
                type: object
                properties:
                  custom_field_label:
                    type: string
                    example: Allocation notes
                  value:
                    type: string
                    example: This allocation is for the annual fund
            custom_field_selected_list_values:
              type: array
              items:
                type: object
                properties:
                  custom_field_label:
                    type: string
                    example: Allocation type
                  value:
                    type: string
                    example: Restricted
  UpdateOpportunity:
    type: object
    required:
    - external_id
    - primary_person_external_id
    - primary_gift_officer
    - opportunity_status_name
    - opportunity_type_name
    properties:
      external_id:
        type: string
        description: Must match an existing opportunity's external ID
        example: OPP-2023-001
      name:
        type: string
      notes:
        type: string
      opportunity_status_name:
        type: string
        description: Must match an existing status
      opportunity_type_name:
        type: string
        description: Must match an existing type
      opportunity_likelihood_name:
        type: string
        description: Must match an existing likelihood
      ask_date:
        type: integer
        description: Unix timestamp in seconds
      expected_response_date:
        type: integer
        description: Unix timestamp in seconds
      response_date:
        type: integer
        description: Unix timestamp in seconds
      ask_amount:
        type: number
        format: float
      accepted_amount:
        type: number
        format: float
      custom_amount_1:
        type: number
        format: float
      expected_close_date:
        type: integer
        description: Unix timestamp in seconds
      expected_ask_amount:
        type: number
        format: float
      expected_amount:
        type: number
        format: float
      expected_ask_date:
        type: integer
        description: Unix timestamp in seconds
      primary_person_external_id:
        type: string
      participant_people_external_ids:
        type: array
        items:
          type: string
      primary_gift_officer:
        type: object
        required:
        - external_id
        properties:
          external_id:
            type: string
          email:
            type: string
      secondary_gift_officers:
        type: array
        items:
          type: object
          properties:
            external_id:
              type: string
            email:
              type: string
      custom_field_boolean_values:
        type: array
        items:
          type: object
          properties:
            custom_field_label:
              type: string
              example: Interested in volunteering
            value:
              type: boolean
              example: true
      custom_field_selected_list_values:
        type: array
        items:
          type: object
          properties:
            custom_field_label:
              type: string
              example: Preferred contact method
            value:
              type: string
              example: Email
      custom_field_string_values:
        type: array
        items:
          type: object
          properties:
            custom_field_label:
              type: string
              example: Notes
            value:
              type: string
              example: Discussed upcoming events and fundraising goals
      opportunity_allocations:
        type: array
        items:
          type: object
          required:
          - opportunity_allocation_amounts
          - designation_id
          - external_id
          properties:
            external_id:
              type: string
            designation_id:
              type: integer
            opportunity_allocation_amounts:
              type: array
              items:
                type: object
                required:
                - amount_type_name
                - amount
                properties:
                  amount_type_name:
                    type: string
                  amount:
                    type: number
                    format: float
            custom_field_string_values:
              type: array
              items:
                type: object
                properties:
                  custom_field_label:
                    type: string
                    example: Allocation notes
                  value:
                    type: string
                    example: This allocation is for the annual fund
            custom_field_selected_list_values:
              type: array
              items:
                type: object
                properties:
                  custom_field_label:
                    type: string
                    example: Allocation type
                  value:
                    type: string
                    example: Restricted
  Opportunity:
    type: object
    description: Response object returned when retrieving opportunities via search
      results download
    properties:
      id:
        type: integer
      external_id:
        type: string
      name:
        type: string
      primary_constituent_external_id:
        type: string
      secondary_constituent_external_ids:
        type: array
        items:
          type: string
      primary_gift_officer_external_id:
        type: string
      secondary_gift_officer_external_ids:
        type: array
        items:
          type: string
      likelihood:
        type: string
      notes:
        type: string
      ask_date:
        type: integer
        description: Unix timestamp in seconds
      expected_response_date:
        type: integer
        description: Unix timestamp in seconds
      response_date:
        type: integer
        description: Unix timestamp in seconds
      ask_amount:
        type: number
        format: float
      received_amount:
        type: number
        format: float
        description: Maps from accepted_amount
      updated_at:
        type: integer
        description: Unix timestamp in seconds
      created_at:
        type: integer
        description: Unix timestamp in seconds
      last_updated_by_gift_officer_external_id:
        type: string
      last_updated_by_email:
        type: string
      status:
        type: string
      type:
        type: string
      creation_source:
        type: string
      solicitation_plan_external_id:
        type: string
      created_by_gc_id:
        type: string
        description: Only populated when creation_source is 'created_by_gc'
      exported_at:
        type: integer
        description: Unix timestamp in seconds
      custom_amount_1:
        type: number
        format: float
      expected_close_date:
        type: integer
        description: Unix timestamp in seconds
      expected_ask_amount:
        type: number
        format: float
      expected_amount:
        type: number
        format: float
      expected_ask_date:
        type: integer
        description: Unix timestamp in seconds
      custom_fields:
        type: array
        items:
          type: object
          properties:
            name:
              type: string
            type:
              type: string
            value:
              type: string
      opportunity_allocations:
        type: array
        items:
          type: object
          properties:
            external_id:
              type: string
            designation_id:
              type: integer
            allocation_amounts:
              type: array
              items:
                type: object
                properties:
                  amount_type_name:
                    type: string
                  amount:
                    type: number
                    format: float
            custom_fields:
              type: array
              items:
                type: object
                properties:
                  name:
                    type: string
                  type:
                    type: string
                  value:
                    type: string
            designation_unique_identifier:
              type: string
            creation_source:
              type: string
  ApiRequest:
    type: object
    properties:
      request_id:
        type: string
        example: abc123
      state:
        type: string
        example: processing
  ApiResults:
    type: object
    properties:
      request_id:
        type: string
      state:
        type: string
        enum:
        - pending
        - processing
        - completed
        - failed
      download_url:
        type: string
        example: https://givecampus.com/api/downloads/request_id.csv
