Govly Tools API

ALPHA REST-callable tool surface for agent and automation workflows over Govly opportunities, awards, workspaces, documents, quote submissions, and inbox items. JSON responses, API-key (bearer or X-API-KEY) authentication, cursor pagination, JSON:API-style error envelope.

OpenAPI Specification

govly-tools-v1-openapi-original.yml Raw ↑
openapi: 3.1.0
info:
  title: Govly Tools API (Alpha)
  version: "1.0.0-alpha"
  description: >
    ALPHA / UNSTABLE: This API is still in active development. Endpoint
    behavior, request fields, response fields, error codes, and operation names
    may change before the Tools API is declared stable.

    REST-callable tool surface for agent and automation workflows. Agents are
    the primary consumer, but integrations can be built on this API. Responses
    are JSON for typed clients; MCP tools may render action results into
    text-oriented formats separately.
servers:
  - url: https://app.govly.com
security:
  - bearerApiKey: []
  - headerApiKey: []
tags:
  - name: Opportunities
    description: Search, fetch, and inspect Govly opportunity records.
  - name: Awards
    description: Search and inspect awarded government contracts.
  - name: Workspaces
    description: Create, update, and inspect opportunity workspaces.
  - name: Workspace Members
    description: Add users and teams to workspaces.
  - name: Workspace Attachments
    description: List and upload workspace attachments.
  - name: Workspace Comments
    description: Post comments to workspaces.
  - name: Follows
    description: Follow opportunities and related workspace activity.
  - name: Saved Searches
    description: List saved opportunity searches and cached matches.
  - name: Documents
    description: Read document representations and request temporary original-file downloads.
  - name: Quote Submissions
    description: Inspect quote submission requirements, submit quotes, and poll submission status.
  - name: Inbox
    description: Read and triage the authenticated user's matched inbox items.
paths:
  /api/tools/v1/opportunities:
    get:
      tags: [Opportunities]
      operationId: fetch_opportunities
      summary: Fetch opportunities by ID
      parameters:
        - name: ids
          in: query
          required: true
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
      responses:
        "200":
          description: Opportunities
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Opportunity"
                  meta:
                    $ref: "#/components/schemas/CountMeta"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/opportunities/{id}:
    get:
      tags: [Opportunities]
      operationId: show_opportunity
      summary: Show an opportunity
      parameters:
        - $ref: "#/components/parameters/id"
      responses:
        "200":
          description: Opportunity
          content:
            application/json:
              schema:
                type: object
                required: [data]
                properties:
                  data:
                    $ref: "#/components/schemas/Opportunity"
                  meta:
                    $ref: "#/components/schemas/ActionMeta"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /api/tools/v1/opportunities/search:
    post:
      tags: [Opportunities]
      operationId: search_opportunities
      summary: Search opportunities
      description: >
        Search opportunities with the constrained public parameter set shared by
        MCP search_opportunities. Defaults to open opportunities and excludes
        prediction records from search results.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                query:
                  type: string
                cursor:
                  type: string
                  description: Opaque cursor from the previous response's meta.nextCursor. Omit for the first page.
                perPage:
                  type: integer
                  default: 25
                  maximum: 100
                status:
                  type: string
                  default: open
                  enum: [open, all, expired, cancelled, awarded, not_cancelled]
                  description: >
                    Defaults to open for actionable opportunities. Use all,
                    expired, cancelled, awarded, or not_cancelled for historical
                    or specific lookup requests. Prediction records are always
                    excluded.
                naics:
                  type: array
                  items:
                    type: string
                  description: NAICS codes to filter by, such as 541519.
                postedAfter:
                  type: string
                  description: Only include opportunities posted at or after this date/time. ISO 8601 dates work best.
                postedBefore:
                  type: string
                  description: Only include opportunities posted at or before this date/time. ISO 8601 dates work best.
                modifiedAfter:
                  type: string
                  description: Only include opportunities modified at or after this date/time. ISO 8601 dates work best.
                modifiedBefore:
                  type: string
                  description: Only include opportunities modified at or before this date/time. ISO 8601 dates work best.
                respondByAfter:
                  type: string
                  description: Only include opportunities with a response deadline at or after this date/time. ISO 8601 dates work best.
                respondByBefore:
                  type: string
                  description: Only include opportunities with a response deadline at or before this date/time. ISO 8601 dates work best.
                awardedAfter:
                  type: string
                  description: Only include awarded opportunities awarded at or after this date/time. ISO 8601 dates work best.
                awardedBefore:
                  type: string
                  description: Only include awarded opportunities awarded at or before this date/time. ISO 8601 dates work best.
                sort:
                  type: string
                  enum: [modified_at, posted_at, respond_by, relevance]
                sortDirection:
                  type: string
                  enum: [asc, desc]
      responses:
        "200":
          description: Matching opportunities
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Opportunity"
                  meta:
                    $ref: "#/components/schemas/CursorMeta"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/awards/{id}:
    get:
      tags: [Awards]
      operationId: show_award
      summary: Show an award
      description: >
        Show a single awarded contract with transactions, sub-awards, related
        opportunities, program links, line items, places, classification codes,
        and contacts. The path parameter accepts
        either identifier shape: an all-digit value is treated as the Govly
        award database id; anything else is treated as the award uniqueKey
        (such as CONT_AWD_... or CONT_IDV_...).
      parameters:
        - $ref: "#/components/parameters/id"
      responses:
        "200":
          description: Award
          content:
            application/json:
              schema:
                type: object
                required: [data]
                properties:
                  data:
                    $ref: "#/components/schemas/Award"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /api/tools/v1/awards/search:
    post:
      tags: [Awards]
      operationId: search_awards
      summary: Search awards
      description: >
        Search awarded government contracts with the constrained public
        parameter set shared by MCP search_awards. Searches all time unless
        dateRange is given. searchType defaults to the authenticated user's
        market focus (fed or sled); sled and international require the matching
        organization subscription.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                query:
                  type: string
                  description: Search text. Supports keywords, quoted phrases, and boolean operators such as AND, OR, and NOT.
                cursor:
                  type: string
                  description: >
                    Opaque pagination token from the previous response's
                    meta.nextCursor. Omit for the first page. Tokens are bound
                    to the query, filters, and sort inputs and carry no format
                    guarantee.
                perPage:
                  type: integer
                  default: 25
                  maximum: 100
                searchType:
                  type: string
                  enum: [fed, sled, international]
                  description: >
                    Market type. Defaults to the authenticated user's market
                    focus (fed or sled). sled and international require the
                    matching organization subscription.
                dateRange:
                  type: array
                  items:
                    type: string
                  minItems: 2
                  maxItems: 2
                  description: Filter by award action dates as [start, end] in ISO 8601 format. Searches all time when omitted.
                recipientNames:
                  type: array
                  items:
                    type: string
                  description: Filter to awards won by any of these recipient (vendor) names.
                buyerNames:
                  type: array
                  items:
                    type: string
                  description: Filter to awards bought by any of these government buyer names.
                funderNames:
                  type: array
                  items:
                    type: string
                  description: Filter to awards funded by any of these government funder names.
                naics:
                  type: array
                  items:
                    type: string
                  description: NAICS codes to filter by, such as 334111.
                psc:
                  type: array
                  items:
                    type: string
                  description: Product or service codes (PSC) to filter by.
                amountRange:
                  type: array
                  items:
                    type: number
                  minItems: 2
                  maxItems: 2
                  description: Filter by award amount as [minimum, maximum].
                sort:
                  type: string
                  enum: [period_of_performance_start_date, awarded_date, last_modified_date, award_amount]
                  description: >-
                    Sort field. Defaults to period_of_performance_start_date. Use awarded_date
                    for recency or award_amount for contract size. SLED awards often lack
                    period_of_performance_start_date, so prefer awarded_date when searchType is sled.
                sortDirection:
                  type: string
                  enum: [asc, desc]
      responses:
        "200":
          description: Matching awards
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Award"
                  meta:
                    $ref: "#/components/schemas/CursorMeta"
        "400":
          $ref: "#/components/responses/Error"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/workspaces:
    get:
      tags: [Workspaces]
      operationId: list_workspaces
      summary: List workspaces associated with an entity
      parameters:
        - $ref: "#/components/parameters/associatedType"
        - $ref: "#/components/parameters/associatedId"
      responses:
        "200":
          description: Matching workspaces
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Workspace"
                  meta:
                    type: object
                    required: [count]
                    properties:
                      count:
                        type: integer
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
    post:
      tags: [Workspaces]
      operationId: create_workspace
      summary: Create a workspace
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              properties:
                name:
                  type: string
                description:
                  type: string
                primaryFocus:
                  $ref: "#/components/schemas/PrimaryFocusInput"
                privateAccess:
                  type: boolean
                workflowStage:
                  type: string
                statusCategory:
                  type: string
                status:
                  type: string
                  description: Human-readable workspace status name, status category, or legacy workflow stage. Prefer this for agent and MCP-style clients.
                workspaceStatusId:
                  type: string
                  description: Current-organization workspace status ID. Prefer status unless the caller already has this ID.
                organizationDefault:
                  type: boolean
                autoFollowCreator:
                  type: boolean
      responses:
        "201":
          description: Created workspace
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkspaceEnvelope"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/workspaces/{id}:
    get:
      tags: [Workspaces]
      operationId: show_workspace
      summary: Show a workspace
      parameters:
        - $ref: "#/components/parameters/id"
      responses:
        "200":
          description: Workspace
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkspaceEnvelope"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
    patch:
      tags: [Workspaces]
      operationId: update_workspace
      summary: Update a workspace
      parameters:
        - $ref: "#/components/parameters/id"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                description:
                  type: string
                privateAccess:
                  type: boolean
                workflowStage:
                  type: string
                statusCategory:
                  type: string
                status:
                  type: string
                  description: Human-readable workspace status name, status category, or legacy workflow stage. Prefer this for agent and MCP-style clients.
                workspaceStatusId:
                  type: string
                  description: Current-organization workspace status ID. Prefer status unless the caller already has this ID.
      responses:
        "200":
          description: Updated workspace
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkspaceEnvelope"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/workspaces/{workspaceId}/members:
    post:
      tags: [Workspace Members]
      operationId: add_workspace_member
      summary: Add a user or team member to a workspace
      parameters:
        - $ref: "#/components/parameters/workspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                userId:
                  type: string
                teamId:
                  type: string
                notifications:
                  type: string
                state:
                  type: string
      responses:
        "201":
          description: Created workspace membership
          content:
            application/json:
              schema:
                type: object
                required: [data]
                properties:
                  data:
                    $ref: "#/components/schemas/WorkspaceMember"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/workspaces/{workspaceId}/attachments:
    get:
      tags: [Workspace Attachments]
      operationId: list_workspace_attachments
      summary: List workspace attachments
      parameters:
        - $ref: "#/components/parameters/workspaceId"
      responses:
        "200":
          description: Workspace attachments
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/WorkspaceAttachment"
                  meta:
                    $ref: "#/components/schemas/CountMeta"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
    post:
      tags: [Workspace Attachments]
      operationId: upload_workspace_attachments
      summary: Upload workspace attachments
      parameters:
        - $ref: "#/components/parameters/workspaceId"
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [attachments]
              properties:
                attachments:
                  type: array
                  items:
                    type: string
                    format: binary
          application/json:
            schema:
              type: object
              required: [attachments]
              properties:
                attachments:
                  type: array
                  items:
                    type: string
                    description: ActiveStorage signed blob ID
      responses:
        "201":
          description: Created attachments
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/WorkspaceAttachment"
                  meta:
                    $ref: "#/components/schemas/CountMeta"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/workspaces/{workspaceId}/comments:
    post:
      tags: [Workspace Comments]
      operationId: create_workspace_comment
      summary: Post a Markdown comment to a workspace
      parameters:
        - $ref: "#/components/parameters/workspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [body]
              properties:
                body:
                  type: string
                  description: Markdown comment body.
      responses:
        "201":
          description: Created workspace comment
          content:
            application/json:
              schema:
                type: object
                required: [data]
                properties:
                  data:
                    $ref: "#/components/schemas/Comment"
                  meta:
                    type: object
                    properties:
                      workspaceId:
                        type: string
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/follows:
    post:
      tags: [Follows]
      operationId: follow_entity
      summary: Follow a Govly entity
      description: >
        Follow, track, or subscribe to changes for a Govly entity. For
        opportunities, this creates or reuses the default opportunity
        workspace and follows that workspace for the authenticated user.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [type, id]
              properties:
                type:
                  type: string
                  enum: [opportunity, opp]
                  description: Entity type to follow. opp is accepted as an alias for opportunity.
                id:
                  type: string
                  description: Govly entity ID.
                notifications:
                  type: string
                  description: Notification preference for this follow. Omit to use the user's default setting.
      responses:
        "201":
          description: Active follow on the entity's default workspace
          content:
            application/json:
              schema:
                type: object
                required: [data]
                properties:
                  data:
                    type: object
                    required: [workspace, membership]
                    properties:
                      workspace:
                        $ref: "#/components/schemas/Workspace"
                      membership:
                        $ref: "#/components/schemas/WorkspaceMember"
                  meta:
                    type: object
                    properties:
                      entityType:
                        type: string
                      entityId:
                        type: string
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/opportunities/{opportunityId}/not_interested:
    post:
      tags: [Opportunities]
      operationId: mark_opportunity_not_interested
      summary: Mark an opportunity not interested
      description: >
        Marks the opportunity not interested / dismissed for the authenticated
        user. Sets a team-visible disinterested status on the user's workspace
        follow, unfollows the user, and dismisses the user's matching inbox
        items.
      parameters:
        - name: opportunityId
          in: path
          required: true
          schema:
            type: string
          description: Govly opportunity ID.
      responses:
        "201":
          description: Opportunity marked not interested
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotInterestedResult"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
    delete:
      tags: [Opportunities]
      operationId: undo_opportunity_not_interested
      summary: Undo a not-interested mark
      description: >
        Removes a previous not-interested mark for the authenticated user and
        restores matching dismissed inbox items. The user returns to a neutral
        (not following) state.
      parameters:
        - name: opportunityId
          in: path
          required: true
          schema:
            type: string
          description: Govly opportunity ID.
      responses:
        "200":
          description: Not-interested mark removed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotInterestedResult"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/opportunities/saved_searches:
    get:
      tags: [Saved Searches]
      operationId: list_opportunity_saved_searches
      summary: List opportunity saved searches
      description: Latest match previews exclude prediction records.
      parameters:
        - $ref: "#/components/parameters/cursor"
        - $ref: "#/components/parameters/perPage"
      responses:
        "200":
          description: Opportunity saved searches
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/OppSearch"
                  meta:
                    $ref: "#/components/schemas/CursorMeta"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/opportunities/saved_searches/{id}:
    get:
      tags: [Saved Searches]
      operationId: show_opportunity_saved_search
      summary: Show an opportunity saved search
      parameters:
        - $ref: "#/components/parameters/id"
      responses:
        "200":
          description: Opportunity saved search
          content:
            application/json:
              schema:
                type: object
                required: [data]
                properties:
                  data:
                    $ref: "#/components/schemas/OppSearch"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
  /api/tools/v1/opportunities/saved_searches/{savedSearchId}/results:
    get:
      tags: [Saved Searches]
      operationId: list_opportunity_saved_search_results
      summary: List cached opportunity results for a saved search
      description: Returns cached saved-search matches, excluding prediction records.
      parameters:
        - $ref: "#/components/parameters/savedSearchId"
        - $ref: "#/components/parameters/cursor"
        - $ref: "#/components/parameters/perPage"
      responses:
        "200":
          description: Cached saved-search matches
          content:
            application/json:
              schema:
                type: object
                required: [data, meta]
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/OppSearchMatch"
                  meta:
                    $ref: "#/components/schemas/CursorMeta"
        "401":
          $ref: "#/components/responses/Error"
        "403":
          $ref: "#/components/responses/Error"
        "404":
          $ref: "#/components/responses/Error"
        "422":
          $ref: "#/components/responses/Error"
  /api/tools/v1/documents/read:
    get:
      tags: [Documents]
      operationId: document_read
      summary: Read bounded document content
      description: >
        Reads a bounded portion of an authorized document without creating an
        analysis or enqueueing extraction work. Start a read with documentType
        and id. Continue when meta.hasMore is true by sending only meta.nextCursor
        and, optionally, maxChars. Cursors are opaque, source-bound, and
        re-authorized on every request. Opportunity document IDs are
        OppAttachment.id values returned as opportunity attachment id;
        access is derived from any associated opportunity/source path visible to
        the caller rather than from a client-supplied opportunity ID.
        Use positioned_text only when data.availableRepresentations advertises it.
        PDF page ranges are supported with pageStart and pageEnd.
        Processing and representation_unavailable are successful structured
        states. Failed or unavailable extraction returns the standard 422 error
        envelope, inaccessible records return the standard 404 error envelope,
        and invalid parameters return the standard 422 error envelope.
      parameters:
        - name: documentType
          in: query
          required: false
          description: Required with id for an initial read. Omit when continuing with cursor.
          schema:
            $ref: "#/components/schemas/DocumentType"
        - name: id
          in: query
          required: false
          description: Required with documentType for an initial read. Omit when continuing with cursor.
          schema:
            type: string
        - name: representation
          in: query
          required: false
          description: Initial-read representation. Omit when continuing with cursor.
          schema:
            $ref: "#/components/schemas/DocumentRepresentation"
        - name: maxChars
          in: query
          required: false
          description: Maximum characters returned in this response.
          schema:
            type: integer
            default: 100000
            minimum: 1
            maximum: 100000
        - name: cursor
          in: query
          required: false
          description: Opaque continuation token from meta.nextCursor. May be combined only with maxChars.
          schema:
            type: string
        - name: pageStart
          in: query
          required: false
          description: First PDF page to read, inclusive. Omit when continuing with cursor.
          schema:
            type: integer
            minimum: 1
        - name: pageEnd


# --- truncated at 32 KB (75 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/govly/refs/heads/main/openapi/govly-tools-v1-openapi-original.yml