> ## Documentation Index
> Fetch the complete documentation index at: https://docs.letterdrop.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Every key of an object, and how to select and filter on it

> Call this first. With object=account (or contact, signal, …) it lists every key the object carries: its type, whether fields= can select it and filter[...] can filter on it, the operators, and the values it takes, with this workspace's competitors, opportunity stages, owners and custom CRM fields filled in. Without object, it lists the objects.



## OpenAPI

````yaml /openapi.json get /fields
openapi: 3.1.0
info:
  title: Letterdrop Competitor Monitoring API
  version: 2.0.0
  license:
    name: Proprietary
    url: https://letterdrop.com/terms
  description: >-
    Read your workspace's Competitor Monitoring data: the accounts where people
    engaged your competitors, the contacts and signals behind each, their CRM
    context, your outreach, and the dashboard metrics.


    The API speaks the same language as the New Competitor Deal webhook (payload
    version v2): a field has the same name and the same values in both, so
    whatever you build on one reads the other.


    **Versioning.** The major version is in the path (/api/v2). Within v2
    changes are additive only (new optional fields, filters, endpoints), so
    ignore fields you do not recognise. The v1 competitor-monitoring endpoints
    keep working unchanged.


    **Rate limits.** Per workspace: 10 requests/second and 600/minute, plus 20
    uncached computations/minute (analytics count as 4). Cached reads
    (meta.cache = hit), including every later page of a list you already
    started, use no computation budget. Every response carries RateLimit-Limit /
    RateLimit-Remaining / RateLimit-Reset; a 429 carries Retry-After.


    **Freshness.** Results are cached for a few minutes (analytics and filter
    options a little longer); meta.data_as_of says when the data was computed.
    Signals are collected daily, so polling faster than every few minutes
    returns the same data.
servers:
  - url: https://api.letterdrop.com/api/v2
security: []
tags:
  - name: Accounts
    description: Companies with competitor signals, and what we know about each.
  - name: Contacts
    description: The people behind the signals.
  - name: Analytics
    description: The dashboard metrics, one endpoint each.
  - name: Filters
    description: Every key of every object, and how to select and filter on it.
externalDocs:
  description: Developer reference
  url: https://api.letterdrop.com/api/v2/docs
paths:
  /fields:
    get:
      tags:
        - Filters
      summary: Every key of an object, and how to select and filter on it
      description: >-
        Call this first. With object=account (or contact, signal, …) it lists
        every key the object carries: its type, whether fields= can select it
        and filter[...] can filter on it, the operators, and the values it
        takes, with this workspace's competitors, opportunity stages, owners and
        custom CRM fields filled in. Without object, it lists the objects.
      operationId: listFields
      parameters:
        - name: object
          in: query
          required: false
          description: The object whose keys to list. Omit to list the objects.
          schema:
            type: string
            enum:
              - account
              - contact
              - signal
              - buying_committee
              - outreach
              - opportunity
              - job_postings
        - name: filterable
          in: query
          required: false
          description: true = only keys filter[...] accepts.
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - meta
                properties:
                  data:
                    $ref: '#/components/schemas/FieldDirectory'
                  meta:
                    $ref: '#/components/schemas/Meta'
              example:
                data:
                  object: account
                  description: >-
                    A company with competitor signals: one row of the table.
                    Contacts (with their signals), the buying committee and the
                    job-postings rollup are nested in it.
                  endpoints:
                    - /accounts
                    - /accounts/lookup
                    - /accounts/{account_id}
                  select: >-
                    fields=<key>,<key>; dotted keys reach into lists
                    (contacts.contact_name).
                  filter:
                    - >-
                      On /accounts: filter[<key>]=<value> or
                      filter[<key>][<operator>]=<value>.
                  keys:
                    - key: account_competitors
                      group: Account
                      type: string
                      description: >-
                        Every competitor with signals at this account,
                        comma-joined ("Common Room, G2"), as the webhook sends
                        it.
                      selectable: true
                      filterable: true
                      operators:
                        - eq
                        - ne
                        - contains
                        - exists
                      fast_operators:
                        - eq
                      values:
                        - HubSpot
                        - Salesforce
                      filter_parameters:
                        - account_competitors
                    - key: account_priority
                      group: Account
                      type: string
                      description: >-
                        How soon to act, as the Competitor Monitoring table
                        shows it. The webhook sends this as signal_priority.
                      selectable: true
                      filterable: true
                      operators:
                        - eq
                        - ne
                        - contains
                        - exists
                      fast_operators:
                        - eq
                      values:
                        - High
                        - Medium
                        - Nurture
                      filter_parameters:
                        - account_priority
                    - key: crm_latest_opp_amount
                      group: CRM
                      type: number
                      nullable: true
                      description: Its amount.
                      selectable: true
                      filterable: true
                      operators:
                        - eq
                        - ne
                        - gt
                        - gte
                        - lt
                        - lte
                        - exists
                    - key: crm_custom_fields
                      group: CRM
                      type: object
                      description: >-
                        The CRM columns you added to the table, keyed
                        "<crm>:<object>:<field>" (e.g. "hubspot:company:Tier"),
                        each a list of values.
                      selectable: true
                      filterable: false
                      filter_parameters:
                        - crm_custom_fields
                      custom_fields:
                        - key: hubspot:company:Tier
                          label: Tier
                          crm_type: hubspot
                          object_type: company
                          name: Tier
                          field_type: text
                          values:
                            - A
                            - B
                    - key: contacts.contact_job_title
                      group: Contact
                      type: string
                      description: Current job title.
                      selectable: true
                      filterable: true
                      operators:
                        - eq
                        - ne
                        - contains
                        - exists
                  filter_parameters:
                    - parameter: search
                      description: Free-text match on company and contact names.
                    - parameter: preset
                      description: >-
                        A prebuilt view of the table. CRM presets replace
                        crm_latest_opp_stage with their own rule.
                      values:
                        - pilot
                        - advertising
                        - capacity_based_outbound
                        - sell_now
                        - competitor_aware_tam
                        - customers_at_risk
                        - competitive_deals
                    - parameter: crm_has_opp
                      description: >-
                        false = accounts with no CRM opportunity. true is the
                        same as listing every crm_latest_opp_stage.
                    - parameter: crm_has_account
                      description: >-
                        true = the account was already in your CRM when we found
                        it, false = net new (it was not). An account added to
                        the CRM later can have crm_account_url set and still be
                        net new.
                  sort:
                    - latest_signal_date
                    - account_priority
                    - crm_latest_opp_created_date
                    - crm_latest_opp_close_date
                  connected_crms:
                    - hubspot
                meta:
                  api_version: '2'
                  data_as_of: '2026-11-02T09:36:28.016Z'
                  cache: hit
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/Unprocessable'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
      security:
        - WorkspaceKey: []
        - BearerAuth:
            - mcp.read
components:
  schemas:
    FieldDirectory:
      type: object
      description: >-
        Every key of one object and how to use it. Without object=, the response
        is { objects: [{ object, description, endpoints }] } instead.
      properties:
        object:
          type: string
          description: The object described.
        description:
          type: string
        endpoints:
          type: array
          items:
            type: string
          description: Where the object appears.
        select:
          type: string
          description: How to select its keys.
        filter:
          type: array
          items:
            type: string
          description: How to filter on its keys, per endpoint.
        keys:
          type: array
          description: >-
            One entry per key, nested keys dotted: key, group, type, nullable,
            description, selectable, filterable, operators, fast_operators
            (operators that narrow the table read itself; the rest filter its
            rows, which reads the whole table on a cold cache), values (when
            they are a known list, this workspace's competitors, stages and
            owners included), filter_parameters (dedicated filters that read the
            key in the table query), requires_include, and for crm_custom_fields
            this workspace's custom_fields with their values.
          items:
            type: object
            additionalProperties: true
        filter_parameters:
          type: array
          items:
            type: object
            additionalProperties: true
          description: >-
            Filters that are not a key of their own (search, preset,
            crm_has_opp, crm_has_account).
        sort:
          type: array
          items:
            type: string
          description: Values sort= takes.
        connected_crms:
          type: array
          items:
            type: string
          description: The workspace's CRMs.
    Meta:
      type: object
      required:
        - api_version
        - data_as_of
        - cache
      properties:
        api_version:
          type: string
          const: '2'
        data_as_of:
          type: string
          format: date-time
          description: >-
            When the data in this response was computed. Responses are cached
            for a few minutes; this tells you how fresh they are.
        cache:
          type: string
          enum:
            - hit
            - miss
            - shared
            - 'off'
          description: >-
            hit = served from cache; miss = computed for this request; shared =
            joined a computation already running for the same query.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - invalid_json
                - invalid_cursor
                - cursor_expired
                - unauthorized
                - forbidden
                - account_not_found
                - not_found
                - rate_limited
                - internal_error
            message:
              type: string
            details:
              type: array
              items:
                type: object
                properties:
                  path:
                    type: string
                  message:
                    type: string
              description: 'For invalid_request: one entry per parameter that failed.'
  responses:
    Unauthorized:
      description: Missing or invalid credential.
      x-status: 401
      x-codes:
        - unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: The credential lacks the mcp.read scope.
      x-status: 403
      x-codes:
        - forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unprocessable:
      description: A parameter failed validation; details lists each one.
      x-status: 422
      x-codes:
        - invalid_request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    TooManyRequests:
      description: Rate limited; wait Retry-After seconds.
      x-status: 429
      x-codes:
        - rate_limited
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait.
    ServerError:
      description: Our fault; retry, and contact support if it persists.
      x-status: 500
      x-codes:
        - internal_error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    WorkspaceKey:
      type: apiKey
      in: header
      name: api-key
    BearerAuth:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.