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

# Report Candidate IP Telemetry

> Report an IP address your own systems observed for a candidate. Ropes stores the reading, enriches it with geolocation and network-concealment intelligence (VPN, proxy, Tor, relay, hosting), and plots it on the candidate's Trust Center as an external source alongside the locations Ropes observed itself. Returns 202 as soon as the reading is stored; enrichment completes asynchronously, so a reading appears on the Trust Center shortly after this call rather than immediately. Reposting an identical (ipAddress, observedAt) pair for the same candidate is a no-op and returns duplicate: true, so retries are safe. The address must be publicly routable — a private, loopback, or link-local address means your system reported an internal IP rather than the public egress address, and is rejected.



## OpenAPI

````yaml https://api.ropes.ai/api/docs/openapi.json post /api/public/candidates/{candidateId}/ip-telemetry
openapi: 3.0.0
info:
  title: Ropes Public API
  version: 1.0.0
  description: >-
    Public API for Ropes. Authenticate using your API key in the x-api-key
    header.
servers:
  - url: https://api.ropes.ai
    description: Production server
  - url: http://localhost:3001
    description: Local development server
security: []
paths:
  /api/public/candidates/{candidateId}/ip-telemetry:
    post:
      tags:
        - Candidates
      summary: Report Candidate IP Telemetry
      description: >-
        Report an IP address your own systems observed for a candidate. Ropes
        stores the reading, enriches it with geolocation and network-concealment
        intelligence (VPN, proxy, Tor, relay, hosting), and plots it on the
        candidate's Trust Center as an external source alongside the locations
        Ropes observed itself. Returns 202 as soon as the reading is stored;
        enrichment completes asynchronously, so a reading appears on the Trust
        Center shortly after this call rather than immediately. Reposting an
        identical (ipAddress, observedAt) pair for the same candidate is a no-op
        and returns duplicate: true, so retries are safe. The address must be
        publicly routable — a private, loopback, or link-local address means
        your system reported an internal IP rather than the public egress
        address, and is rejected.
      parameters:
        - schema:
            type: string
            description: The unique identifier of the candidate
          required: true
          description: The unique identifier of the candidate
          name: candidateId
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateExternalIpTelemetryRequest'
      responses:
        '202':
          description: Reading accepted for enrichment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateExternalIpTelemetryResponse'
        '400':
          description: Bad request - Invalid IP address, timestamp, or unknown field
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIpTelemetryErrorResponse'
        '401':
          description: Unauthorized - Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIpTelemetryErrorResponse'
        '404':
          description: Candidate not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIpTelemetryErrorResponse'
        '429':
          description: >-
            Rate limit exceeded - contact support@ropes.ai for further
            assistance.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIpTelemetryErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIpTelemetryErrorResponse'
      security:
        - ApiKeyAuth: []
components:
  schemas:
    CreateExternalIpTelemetryRequest:
      type: object
      properties:
        ipAddress:
          type: string
          description: >-
            The publicly routable IPv4 or IPv6 address observed for the
            candidate, e.g. 93.184.216.34
        observedAt:
          type: string
          format: date-time
          description: >-
            ISO 8601 / RFC 3339 timestamp of when the external provider observed
            the IP. A UTC offset is accepted, e.g. 2026-08-25T12:00:00Z or
            2026-08-25T21:00:00+09:00
        source:
          type: string
          minLength: 1
          maxLength: 64
          description: >-
            Name of the system that observed the IP, shown to reviewers on the
            Trust Center, e.g. "acme-proctor"
      required:
        - ipAddress
        - observedAt
        - source
      additionalProperties: false
    CreateExternalIpTelemetryResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - accepted
          description: The reading was accepted for enrichment
        id:
          type: string
          nullable: true
          description: Identifier of the stored reading, or null when it was a duplicate
        duplicate:
          type: boolean
          description: True when an identical reading for this candidate was already stored
      required:
        - status
        - id
        - duplicate
    ExternalIpTelemetryErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Error message
        details:
          nullable: true
          description: Validation issues, when the request was malformed
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````